devops tenant api

Signed-off-by: runzexia <runzexia@yunify.com>
This commit is contained in:
runzexia
2019-04-23 20:47:47 +08:00
committed by zryfish
parent 78f2dab18c
commit 5a6f51d775
143 changed files with 19533 additions and 341 deletions

21
vendor/github.com/asaskevich/govalidator/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Alex Saskevich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

58
vendor/github.com/asaskevich/govalidator/arrays.go generated vendored Normal file
View File

@@ -0,0 +1,58 @@
package govalidator
// Iterator is the function that accepts element of slice/array and its index
type Iterator func(interface{}, int)
// ResultIterator is the function that accepts element of slice/array and its index and returns any result
type ResultIterator func(interface{}, int) interface{}
// ConditionIterator is the function that accepts element of slice/array and its index and returns boolean
type ConditionIterator func(interface{}, int) bool
// Each iterates over the slice and apply Iterator to every item
func Each(array []interface{}, iterator Iterator) {
for index, data := range array {
iterator(data, index)
}
}
// Map iterates over the slice and apply ResultIterator to every item. Returns new slice as a result.
func Map(array []interface{}, iterator ResultIterator) []interface{} {
var result = make([]interface{}, len(array))
for index, data := range array {
result[index] = iterator(data, index)
}
return result
}
// Find iterates over the slice and apply ConditionIterator to every item. Returns first item that meet ConditionIterator or nil otherwise.
func Find(array []interface{}, iterator ConditionIterator) interface{} {
for index, data := range array {
if iterator(data, index) {
return data
}
}
return nil
}
// Filter iterates over the slice and apply ConditionIterator to every item. Returns new slice.
func Filter(array []interface{}, iterator ConditionIterator) []interface{} {
var result = make([]interface{}, 0)
for index, data := range array {
if iterator(data, index) {
result = append(result, data)
}
}
return result
}
// Count iterates over the slice and apply ConditionIterator to every item. Returns count of items that meets ConditionIterator.
func Count(array []interface{}, iterator ConditionIterator) int {
count := 0
for index, data := range array {
if iterator(data, index) {
count = count + 1
}
}
return count
}

64
vendor/github.com/asaskevich/govalidator/converter.go generated vendored Normal file
View File

@@ -0,0 +1,64 @@
package govalidator
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
)
// ToString convert the input to a string.
func ToString(obj interface{}) string {
res := fmt.Sprintf("%v", obj)
return string(res)
}
// ToJSON convert the input to a valid JSON string
func ToJSON(obj interface{}) (string, error) {
res, err := json.Marshal(obj)
if err != nil {
res = []byte("")
}
return string(res), err
}
// ToFloat convert the input string to a float, or 0.0 if the input is not a float.
func ToFloat(str string) (float64, error) {
res, err := strconv.ParseFloat(str, 64)
if err != nil {
res = 0.0
}
return res, err
}
// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer.
func ToInt(value interface{}) (res int64, err error) {
val := reflect.ValueOf(value)
switch value.(type) {
case int, int8, int16, int32, int64:
res = val.Int()
case uint, uint8, uint16, uint32, uint64:
res = int64(val.Uint())
case string:
if IsInt(val.String()) {
res, err = strconv.ParseInt(val.String(), 0, 64)
if err != nil {
res = 0
}
} else {
err = fmt.Errorf("math: square root of negative number %g", value)
res = 0
}
default:
err = fmt.Errorf("math: square root of negative number %g", value)
res = 0
}
return
}
// ToBoolean convert the input string to a boolean.
func ToBoolean(str string) (bool, error) {
return strconv.ParseBool(str)
}

36
vendor/github.com/asaskevich/govalidator/error.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
package govalidator
import "strings"
// Errors is an array of multiple errors and conforms to the error interface.
type Errors []error
// Errors returns itself.
func (es Errors) Errors() []error {
return es
}
func (es Errors) Error() string {
var errs []string
for _, e := range es {
errs = append(errs, e.Error())
}
return strings.Join(errs, ";")
}
// Error encapsulates a name, an error and whether there's a custom error message or not.
type Error struct {
Name string
Err error
CustomErrorMessageExists bool
// Validator indicates the name of the validator that failed
Validator string
}
func (e Error) Error() string {
if e.CustomErrorMessageExists {
return e.Err.Error()
}
return e.Name + ": " + e.Err.Error()
}

97
vendor/github.com/asaskevich/govalidator/numerics.go generated vendored Normal file
View File

@@ -0,0 +1,97 @@
package govalidator
import (
"math"
"reflect"
)
// Abs returns absolute value of number
func Abs(value float64) float64 {
return math.Abs(value)
}
// Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise
func Sign(value float64) float64 {
if value > 0 {
return 1
} else if value < 0 {
return -1
} else {
return 0
}
}
// IsNegative returns true if value < 0
func IsNegative(value float64) bool {
return value < 0
}
// IsPositive returns true if value > 0
func IsPositive(value float64) bool {
return value > 0
}
// IsNonNegative returns true if value >= 0
func IsNonNegative(value float64) bool {
return value >= 0
}
// IsNonPositive returns true if value <= 0
func IsNonPositive(value float64) bool {
return value <= 0
}
// InRange returns true if value lies between left and right border
func InRangeInt(value, left, right interface{}) bool {
value64, _ := ToInt(value)
left64, _ := ToInt(left)
right64, _ := ToInt(right)
if left64 > right64 {
left64, right64 = right64, left64
}
return value64 >= left64 && value64 <= right64
}
// InRange returns true if value lies between left and right border
func InRangeFloat32(value, left, right float32) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}
// InRange returns true if value lies between left and right border
func InRangeFloat64(value, left, right float64) bool {
if left > right {
left, right = right, left
}
return value >= left && value <= right
}
// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type
func InRange(value interface{}, left interface{}, right interface{}) bool {
reflectValue := reflect.TypeOf(value).Kind()
reflectLeft := reflect.TypeOf(left).Kind()
reflectRight := reflect.TypeOf(right).Kind()
if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int {
return InRangeInt(value.(int), left.(int), right.(int))
} else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 {
return InRangeFloat32(value.(float32), left.(float32), right.(float32))
} else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 {
return InRangeFloat64(value.(float64), left.(float64), right.(float64))
} else {
return false
}
}
// IsWhole returns true if value is whole number
func IsWhole(value float64) bool {
return math.Remainder(value, 1) == 0
}
// IsNatural returns true if value is natural number (positive and whole)
func IsNatural(value float64) bool {
return IsWhole(value) && IsPositive(value)
}

97
vendor/github.com/asaskevich/govalidator/patterns.go generated vendored Normal file
View File

@@ -0,0 +1,97 @@
package govalidator
import "regexp"
// Basic regular expressions for validating strings
const (
//Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$"
ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$"
ISBN13 string = "^(?:[0-9]{13})$"
UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
Alpha string = "^[a-zA-Z]+$"
Alphanumeric string = "^[a-zA-Z0-9]+$"
Numeric string = "^[0-9]+$"
Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$"
Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$"
Hexadecimal string = "^[0-9a-fA-F]+$"
Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
ASCII string = "^[\x00-\x7F]+$"
Multibyte string = "[^\x00-\x7F]"
FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]"
Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
PrintableASCII string = "^[\x20-\x7E]+$"
DataURI string = "^data:.+\\/(.+);base64$"
Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$`
IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)`
URLUsername string = `(\S+(:\S*)?@)`
URLPath string = `((\/|\?|#)[^\s]*)`
URLPort string = `(:(\d{1,5}))`
URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))`
URLSubdomain string = `((www\.)|([a-zA-Z0-9]([-\.][-\._a-zA-Z0-9]+)*))`
URL string = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`
SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
UnixPath string = `^(/[^/\x00]*)+/?$`
Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
tagName string = "valid"
hasLowerCase string = ".*[[:lower:]]"
hasUpperCase string = ".*[[:upper:]]"
)
// Used by IsFilePath func
const (
// Unknown is unresolved OS type
Unknown = iota
// Win is Windows type
Win
// Unix is *nix OS types
Unix
)
var (
userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$")
hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$")
userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})")
//rxEmail = regexp.MustCompile(Email)
rxCreditCard = regexp.MustCompile(CreditCard)
rxISBN10 = regexp.MustCompile(ISBN10)
rxISBN13 = regexp.MustCompile(ISBN13)
rxUUID3 = regexp.MustCompile(UUID3)
rxUUID4 = regexp.MustCompile(UUID4)
rxUUID5 = regexp.MustCompile(UUID5)
rxUUID = regexp.MustCompile(UUID)
rxAlpha = regexp.MustCompile(Alpha)
rxAlphanumeric = regexp.MustCompile(Alphanumeric)
rxNumeric = regexp.MustCompile(Numeric)
rxInt = regexp.MustCompile(Int)
rxFloat = regexp.MustCompile(Float)
rxHexadecimal = regexp.MustCompile(Hexadecimal)
rxHexcolor = regexp.MustCompile(Hexcolor)
rxRGBcolor = regexp.MustCompile(RGBcolor)
rxASCII = regexp.MustCompile(ASCII)
rxPrintableASCII = regexp.MustCompile(PrintableASCII)
rxMultibyte = regexp.MustCompile(Multibyte)
rxFullWidth = regexp.MustCompile(FullWidth)
rxHalfWidth = regexp.MustCompile(HalfWidth)
rxBase64 = regexp.MustCompile(Base64)
rxDataURI = regexp.MustCompile(DataURI)
rxLatitude = regexp.MustCompile(Latitude)
rxLongitude = regexp.MustCompile(Longitude)
rxDNSName = regexp.MustCompile(DNSName)
rxURL = regexp.MustCompile(URL)
rxSSN = regexp.MustCompile(SSN)
rxWinPath = regexp.MustCompile(WinPath)
rxUnixPath = regexp.MustCompile(UnixPath)
rxSemver = regexp.MustCompile(Semver)
rxHasLowerCase = regexp.MustCompile(hasLowerCase)
rxHasUpperCase = regexp.MustCompile(hasUpperCase)
)

616
vendor/github.com/asaskevich/govalidator/types.go generated vendored Normal file
View File

@@ -0,0 +1,616 @@
package govalidator
import (
"reflect"
"regexp"
"sync"
)
// Validator is a wrapper for a validator function that returns bool and accepts string.
type Validator func(str string) bool
// CustomTypeValidator is a wrapper for validator functions that returns bool and accepts any type.
// The second parameter should be the context (in the case of validating a struct: the whole object being validated).
type CustomTypeValidator func(i interface{}, o interface{}) bool
// ParamValidator is a wrapper for validator functions that accepts additional parameters.
type ParamValidator func(str string, params ...string) bool
type tagOptionsMap map[string]string
// UnsupportedTypeError is a wrapper for reflect.Type
type UnsupportedTypeError struct {
Type reflect.Type
}
// stringValues is a slice of reflect.Value holding *reflect.StringValue.
// It implements the methods to sort by string.
type stringValues []reflect.Value
// ParamTagMap is a map of functions accept variants parameters
var ParamTagMap = map[string]ParamValidator{
"length": ByteLength,
"range": Range,
"runelength": RuneLength,
"stringlength": StringLength,
"matches": StringMatches,
"in": isInRaw,
"rsapub": IsRsaPub,
}
// ParamTagRegexMap maps param tags to their respective regexes.
var ParamTagRegexMap = map[string]*regexp.Regexp{
"range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"),
"length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"),
"runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"),
"stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"),
"in": regexp.MustCompile(`^in\((.*)\)`),
"matches": regexp.MustCompile(`^matches\((.+)\)$`),
"rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"),
}
type customTypeTagMap struct {
validators map[string]CustomTypeValidator
sync.RWMutex
}
func (tm *customTypeTagMap) Get(name string) (CustomTypeValidator, bool) {
tm.RLock()
defer tm.RUnlock()
v, ok := tm.validators[name]
return v, ok
}
func (tm *customTypeTagMap) Set(name string, ctv CustomTypeValidator) {
tm.Lock()
defer tm.Unlock()
tm.validators[name] = ctv
}
// CustomTypeTagMap is a map of functions that can be used as tags for ValidateStruct function.
// Use this to validate compound or custom types that need to be handled as a whole, e.g.
// `type UUID [16]byte` (this would be handled as an array of bytes).
var CustomTypeTagMap = &customTypeTagMap{validators: make(map[string]CustomTypeValidator)}
// TagMap is a map of functions, that can be used as tags for ValidateStruct function.
var TagMap = map[string]Validator{
"email": IsEmail,
"url": IsURL,
"dialstring": IsDialString,
"requrl": IsRequestURL,
"requri": IsRequestURI,
"alpha": IsAlpha,
"utfletter": IsUTFLetter,
"alphanum": IsAlphanumeric,
"utfletternum": IsUTFLetterNumeric,
"numeric": IsNumeric,
"utfnumeric": IsUTFNumeric,
"utfdigit": IsUTFDigit,
"hexadecimal": IsHexadecimal,
"hexcolor": IsHexcolor,
"rgbcolor": IsRGBcolor,
"lowercase": IsLowerCase,
"uppercase": IsUpperCase,
"int": IsInt,
"float": IsFloat,
"null": IsNull,
"uuid": IsUUID,
"uuidv3": IsUUIDv3,
"uuidv4": IsUUIDv4,
"uuidv5": IsUUIDv5,
"creditcard": IsCreditCard,
"isbn10": IsISBN10,
"isbn13": IsISBN13,
"json": IsJSON,
"multibyte": IsMultibyte,
"ascii": IsASCII,
"printableascii": IsPrintableASCII,
"fullwidth": IsFullWidth,
"halfwidth": IsHalfWidth,
"variablewidth": IsVariableWidth,
"base64": IsBase64,
"datauri": IsDataURI,
"ip": IsIP,
"port": IsPort,
"ipv4": IsIPv4,
"ipv6": IsIPv6,
"dns": IsDNSName,
"host": IsHost,
"mac": IsMAC,
"latitude": IsLatitude,
"longitude": IsLongitude,
"ssn": IsSSN,
"semver": IsSemver,
"rfc3339": IsRFC3339,
"rfc3339WithoutZone": IsRFC3339WithoutZone,
"ISO3166Alpha2": IsISO3166Alpha2,
"ISO3166Alpha3": IsISO3166Alpha3,
"ISO4217": IsISO4217,
}
// ISO3166Entry stores country codes
type ISO3166Entry struct {
EnglishShortName string
FrenchShortName string
Alpha2Code string
Alpha3Code string
Numeric string
}
//ISO3166List based on https://www.iso.org/obp/ui/#search/code/ Code Type "Officially Assigned Codes"
var ISO3166List = []ISO3166Entry{
{"Afghanistan", "Afghanistan (l')", "AF", "AFG", "004"},
{"Albania", "Albanie (l')", "AL", "ALB", "008"},
{"Antarctica", "Antarctique (l')", "AQ", "ATA", "010"},
{"Algeria", "Algérie (l')", "DZ", "DZA", "012"},
{"American Samoa", "Samoa américaines (les)", "AS", "ASM", "016"},
{"Andorra", "Andorre (l')", "AD", "AND", "020"},
{"Angola", "Angola (l')", "AO", "AGO", "024"},
{"Antigua and Barbuda", "Antigua-et-Barbuda", "AG", "ATG", "028"},
{"Azerbaijan", "Azerbaïdjan (l')", "AZ", "AZE", "031"},
{"Argentina", "Argentine (l')", "AR", "ARG", "032"},
{"Australia", "Australie (l')", "AU", "AUS", "036"},
{"Austria", "Autriche (l')", "AT", "AUT", "040"},
{"Bahamas (the)", "Bahamas (les)", "BS", "BHS", "044"},
{"Bahrain", "Bahreïn", "BH", "BHR", "048"},
{"Bangladesh", "Bangladesh (le)", "BD", "BGD", "050"},
{"Armenia", "Arménie (l')", "AM", "ARM", "051"},
{"Barbados", "Barbade (la)", "BB", "BRB", "052"},
{"Belgium", "Belgique (la)", "BE", "BEL", "056"},
{"Bermuda", "Bermudes (les)", "BM", "BMU", "060"},
{"Bhutan", "Bhoutan (le)", "BT", "BTN", "064"},
{"Bolivia (Plurinational State of)", "Bolivie (État plurinational de)", "BO", "BOL", "068"},
{"Bosnia and Herzegovina", "Bosnie-Herzégovine (la)", "BA", "BIH", "070"},
{"Botswana", "Botswana (le)", "BW", "BWA", "072"},
{"Bouvet Island", "Bouvet (l'Île)", "BV", "BVT", "074"},
{"Brazil", "Brésil (le)", "BR", "BRA", "076"},
{"Belize", "Belize (le)", "BZ", "BLZ", "084"},
{"British Indian Ocean Territory (the)", "Indien (le Territoire britannique de l'océan)", "IO", "IOT", "086"},
{"Solomon Islands", "Salomon (Îles)", "SB", "SLB", "090"},
{"Virgin Islands (British)", "Vierges britanniques (les Îles)", "VG", "VGB", "092"},
{"Brunei Darussalam", "Brunéi Darussalam (le)", "BN", "BRN", "096"},
{"Bulgaria", "Bulgarie (la)", "BG", "BGR", "100"},
{"Myanmar", "Myanmar (le)", "MM", "MMR", "104"},
{"Burundi", "Burundi (le)", "BI", "BDI", "108"},
{"Belarus", "Bélarus (le)", "BY", "BLR", "112"},
{"Cambodia", "Cambodge (le)", "KH", "KHM", "116"},
{"Cameroon", "Cameroun (le)", "CM", "CMR", "120"},
{"Canada", "Canada (le)", "CA", "CAN", "124"},
{"Cabo Verde", "Cabo Verde", "CV", "CPV", "132"},
{"Cayman Islands (the)", "Caïmans (les Îles)", "KY", "CYM", "136"},
{"Central African Republic (the)", "République centrafricaine (la)", "CF", "CAF", "140"},
{"Sri Lanka", "Sri Lanka", "LK", "LKA", "144"},
{"Chad", "Tchad (le)", "TD", "TCD", "148"},
{"Chile", "Chili (le)", "CL", "CHL", "152"},
{"China", "Chine (la)", "CN", "CHN", "156"},
{"Taiwan (Province of China)", "Taïwan (Province de Chine)", "TW", "TWN", "158"},
{"Christmas Island", "Christmas (l'Île)", "CX", "CXR", "162"},
{"Cocos (Keeling) Islands (the)", "Cocos (les Îles)/ Keeling (les Îles)", "CC", "CCK", "166"},
{"Colombia", "Colombie (la)", "CO", "COL", "170"},
{"Comoros (the)", "Comores (les)", "KM", "COM", "174"},
{"Mayotte", "Mayotte", "YT", "MYT", "175"},
{"Congo (the)", "Congo (le)", "CG", "COG", "178"},
{"Congo (the Democratic Republic of the)", "Congo (la République démocratique du)", "CD", "COD", "180"},
{"Cook Islands (the)", "Cook (les Îles)", "CK", "COK", "184"},
{"Costa Rica", "Costa Rica (le)", "CR", "CRI", "188"},
{"Croatia", "Croatie (la)", "HR", "HRV", "191"},
{"Cuba", "Cuba", "CU", "CUB", "192"},
{"Cyprus", "Chypre", "CY", "CYP", "196"},
{"Czech Republic (the)", "tchèque (la République)", "CZ", "CZE", "203"},
{"Benin", "Bénin (le)", "BJ", "BEN", "204"},
{"Denmark", "Danemark (le)", "DK", "DNK", "208"},
{"Dominica", "Dominique (la)", "DM", "DMA", "212"},
{"Dominican Republic (the)", "dominicaine (la République)", "DO", "DOM", "214"},
{"Ecuador", "Équateur (l')", "EC", "ECU", "218"},
{"El Salvador", "El Salvador", "SV", "SLV", "222"},
{"Equatorial Guinea", "Guinée équatoriale (la)", "GQ", "GNQ", "226"},
{"Ethiopia", "Éthiopie (l')", "ET", "ETH", "231"},
{"Eritrea", "Érythrée (l')", "ER", "ERI", "232"},
{"Estonia", "Estonie (l')", "EE", "EST", "233"},
{"Faroe Islands (the)", "Féroé (les Îles)", "FO", "FRO", "234"},
{"Falkland Islands (the) [Malvinas]", "Falkland (les Îles)/Malouines (les Îles)", "FK", "FLK", "238"},
{"South Georgia and the South Sandwich Islands", "Géorgie du Sud-et-les Îles Sandwich du Sud (la)", "GS", "SGS", "239"},
{"Fiji", "Fidji (les)", "FJ", "FJI", "242"},
{"Finland", "Finlande (la)", "FI", "FIN", "246"},
{"Åland Islands", "Åland(les Îles)", "AX", "ALA", "248"},
{"France", "France (la)", "FR", "FRA", "250"},
{"French Guiana", "Guyane française (la )", "GF", "GUF", "254"},
{"French Polynesia", "Polynésie française (la)", "PF", "PYF", "258"},
{"French Southern Territories (the)", "Terres australes françaises (les)", "TF", "ATF", "260"},
{"Djibouti", "Djibouti", "DJ", "DJI", "262"},
{"Gabon", "Gabon (le)", "GA", "GAB", "266"},
{"Georgia", "Géorgie (la)", "GE", "GEO", "268"},
{"Gambia (the)", "Gambie (la)", "GM", "GMB", "270"},
{"Palestine, State of", "Palestine, État de", "PS", "PSE", "275"},
{"Germany", "Allemagne (l')", "DE", "DEU", "276"},
{"Ghana", "Ghana (le)", "GH", "GHA", "288"},
{"Gibraltar", "Gibraltar", "GI", "GIB", "292"},
{"Kiribati", "Kiribati", "KI", "KIR", "296"},
{"Greece", "Grèce (la)", "GR", "GRC", "300"},
{"Greenland", "Groenland (le)", "GL", "GRL", "304"},
{"Grenada", "Grenade (la)", "GD", "GRD", "308"},
{"Guadeloupe", "Guadeloupe (la)", "GP", "GLP", "312"},
{"Guam", "Guam", "GU", "GUM", "316"},
{"Guatemala", "Guatemala (le)", "GT", "GTM", "320"},
{"Guinea", "Guinée (la)", "GN", "GIN", "324"},
{"Guyana", "Guyana (le)", "GY", "GUY", "328"},
{"Haiti", "Haïti", "HT", "HTI", "332"},
{"Heard Island and McDonald Islands", "Heard-et-Îles MacDonald (l'Île)", "HM", "HMD", "334"},
{"Holy See (the)", "Saint-Siège (le)", "VA", "VAT", "336"},
{"Honduras", "Honduras (le)", "HN", "HND", "340"},
{"Hong Kong", "Hong Kong", "HK", "HKG", "344"},
{"Hungary", "Hongrie (la)", "HU", "HUN", "348"},
{"Iceland", "Islande (l')", "IS", "ISL", "352"},
{"India", "Inde (l')", "IN", "IND", "356"},
{"Indonesia", "Indonésie (l')", "ID", "IDN", "360"},
{"Iran (Islamic Republic of)", "Iran (République Islamique d')", "IR", "IRN", "364"},
{"Iraq", "Iraq (l')", "IQ", "IRQ", "368"},
{"Ireland", "Irlande (l')", "IE", "IRL", "372"},
{"Israel", "Israël", "IL", "ISR", "376"},
{"Italy", "Italie (l')", "IT", "ITA", "380"},
{"Côte d'Ivoire", "Côte d'Ivoire (la)", "CI", "CIV", "384"},
{"Jamaica", "Jamaïque (la)", "JM", "JAM", "388"},
{"Japan", "Japon (le)", "JP", "JPN", "392"},
{"Kazakhstan", "Kazakhstan (le)", "KZ", "KAZ", "398"},
{"Jordan", "Jordanie (la)", "JO", "JOR", "400"},
{"Kenya", "Kenya (le)", "KE", "KEN", "404"},
{"Korea (the Democratic People's Republic of)", "Corée (la République populaire démocratique de)", "KP", "PRK", "408"},
{"Korea (the Republic of)", "Corée (la République de)", "KR", "KOR", "410"},
{"Kuwait", "Koweït (le)", "KW", "KWT", "414"},
{"Kyrgyzstan", "Kirghizistan (le)", "KG", "KGZ", "417"},
{"Lao People's Democratic Republic (the)", "Lao, République démocratique populaire", "LA", "LAO", "418"},
{"Lebanon", "Liban (le)", "LB", "LBN", "422"},
{"Lesotho", "Lesotho (le)", "LS", "LSO", "426"},
{"Latvia", "Lettonie (la)", "LV", "LVA", "428"},
{"Liberia", "Libéria (le)", "LR", "LBR", "430"},
{"Libya", "Libye (la)", "LY", "LBY", "434"},
{"Liechtenstein", "Liechtenstein (le)", "LI", "LIE", "438"},
{"Lithuania", "Lituanie (la)", "LT", "LTU", "440"},
{"Luxembourg", "Luxembourg (le)", "LU", "LUX", "442"},
{"Macao", "Macao", "MO", "MAC", "446"},
{"Madagascar", "Madagascar", "MG", "MDG", "450"},
{"Malawi", "Malawi (le)", "MW", "MWI", "454"},
{"Malaysia", "Malaisie (la)", "MY", "MYS", "458"},
{"Maldives", "Maldives (les)", "MV", "MDV", "462"},
{"Mali", "Mali (le)", "ML", "MLI", "466"},
{"Malta", "Malte", "MT", "MLT", "470"},
{"Martinique", "Martinique (la)", "MQ", "MTQ", "474"},
{"Mauritania", "Mauritanie (la)", "MR", "MRT", "478"},
{"Mauritius", "Maurice", "MU", "MUS", "480"},
{"Mexico", "Mexique (le)", "MX", "MEX", "484"},
{"Monaco", "Monaco", "MC", "MCO", "492"},
{"Mongolia", "Mongolie (la)", "MN", "MNG", "496"},
{"Moldova (the Republic of)", "Moldova , République de", "MD", "MDA", "498"},
{"Montenegro", "Monténégro (le)", "ME", "MNE", "499"},
{"Montserrat", "Montserrat", "MS", "MSR", "500"},
{"Morocco", "Maroc (le)", "MA", "MAR", "504"},
{"Mozambique", "Mozambique (le)", "MZ", "MOZ", "508"},
{"Oman", "Oman", "OM", "OMN", "512"},
{"Namibia", "Namibie (la)", "NA", "NAM", "516"},
{"Nauru", "Nauru", "NR", "NRU", "520"},
{"Nepal", "Népal (le)", "NP", "NPL", "524"},
{"Netherlands (the)", "Pays-Bas (les)", "NL", "NLD", "528"},
{"Curaçao", "Curaçao", "CW", "CUW", "531"},
{"Aruba", "Aruba", "AW", "ABW", "533"},
{"Sint Maarten (Dutch part)", "Saint-Martin (partie néerlandaise)", "SX", "SXM", "534"},
{"Bonaire, Sint Eustatius and Saba", "Bonaire, Saint-Eustache et Saba", "BQ", "BES", "535"},
{"New Caledonia", "Nouvelle-Calédonie (la)", "NC", "NCL", "540"},
{"Vanuatu", "Vanuatu (le)", "VU", "VUT", "548"},
{"New Zealand", "Nouvelle-Zélande (la)", "NZ", "NZL", "554"},
{"Nicaragua", "Nicaragua (le)", "NI", "NIC", "558"},
{"Niger (the)", "Niger (le)", "NE", "NER", "562"},
{"Nigeria", "Nigéria (le)", "NG", "NGA", "566"},
{"Niue", "Niue", "NU", "NIU", "570"},
{"Norfolk Island", "Norfolk (l'Île)", "NF", "NFK", "574"},
{"Norway", "Norvège (la)", "NO", "NOR", "578"},
{"Northern Mariana Islands (the)", "Mariannes du Nord (les Îles)", "MP", "MNP", "580"},
{"United States Minor Outlying Islands (the)", "Îles mineures éloignées des États-Unis (les)", "UM", "UMI", "581"},
{"Micronesia (Federated States of)", "Micronésie (États fédérés de)", "FM", "FSM", "583"},
{"Marshall Islands (the)", "Marshall (Îles)", "MH", "MHL", "584"},
{"Palau", "Palaos (les)", "PW", "PLW", "585"},
{"Pakistan", "Pakistan (le)", "PK", "PAK", "586"},
{"Panama", "Panama (le)", "PA", "PAN", "591"},
{"Papua New Guinea", "Papouasie-Nouvelle-Guinée (la)", "PG", "PNG", "598"},
{"Paraguay", "Paraguay (le)", "PY", "PRY", "600"},
{"Peru", "Pérou (le)", "PE", "PER", "604"},
{"Philippines (the)", "Philippines (les)", "PH", "PHL", "608"},
{"Pitcairn", "Pitcairn", "PN", "PCN", "612"},
{"Poland", "Pologne (la)", "PL", "POL", "616"},
{"Portugal", "Portugal (le)", "PT", "PRT", "620"},
{"Guinea-Bissau", "Guinée-Bissau (la)", "GW", "GNB", "624"},
{"Timor-Leste", "Timor-Leste (le)", "TL", "TLS", "626"},
{"Puerto Rico", "Porto Rico", "PR", "PRI", "630"},
{"Qatar", "Qatar (le)", "QA", "QAT", "634"},
{"Réunion", "Réunion (La)", "RE", "REU", "638"},
{"Romania", "Roumanie (la)", "RO", "ROU", "642"},
{"Russian Federation (the)", "Russie (la Fédération de)", "RU", "RUS", "643"},
{"Rwanda", "Rwanda (le)", "RW", "RWA", "646"},
{"Saint Barthélemy", "Saint-Barthélemy", "BL", "BLM", "652"},
{"Saint Helena, Ascension and Tristan da Cunha", "Sainte-Hélène, Ascension et Tristan da Cunha", "SH", "SHN", "654"},
{"Saint Kitts and Nevis", "Saint-Kitts-et-Nevis", "KN", "KNA", "659"},
{"Anguilla", "Anguilla", "AI", "AIA", "660"},
{"Saint Lucia", "Sainte-Lucie", "LC", "LCA", "662"},
{"Saint Martin (French part)", "Saint-Martin (partie française)", "MF", "MAF", "663"},
{"Saint Pierre and Miquelon", "Saint-Pierre-et-Miquelon", "PM", "SPM", "666"},
{"Saint Vincent and the Grenadines", "Saint-Vincent-et-les Grenadines", "VC", "VCT", "670"},
{"San Marino", "Saint-Marin", "SM", "SMR", "674"},
{"Sao Tome and Principe", "Sao Tomé-et-Principe", "ST", "STP", "678"},
{"Saudi Arabia", "Arabie saoudite (l')", "SA", "SAU", "682"},
{"Senegal", "Sénégal (le)", "SN", "SEN", "686"},
{"Serbia", "Serbie (la)", "RS", "SRB", "688"},
{"Seychelles", "Seychelles (les)", "SC", "SYC", "690"},
{"Sierra Leone", "Sierra Leone (la)", "SL", "SLE", "694"},
{"Singapore", "Singapour", "SG", "SGP", "702"},
{"Slovakia", "Slovaquie (la)", "SK", "SVK", "703"},
{"Viet Nam", "Viet Nam (le)", "VN", "VNM", "704"},
{"Slovenia", "Slovénie (la)", "SI", "SVN", "705"},
{"Somalia", "Somalie (la)", "SO", "SOM", "706"},
{"South Africa", "Afrique du Sud (l')", "ZA", "ZAF", "710"},
{"Zimbabwe", "Zimbabwe (le)", "ZW", "ZWE", "716"},
{"Spain", "Espagne (l')", "ES", "ESP", "724"},
{"South Sudan", "Soudan du Sud (le)", "SS", "SSD", "728"},
{"Sudan (the)", "Soudan (le)", "SD", "SDN", "729"},
{"Western Sahara*", "Sahara occidental (le)*", "EH", "ESH", "732"},
{"Suriname", "Suriname (le)", "SR", "SUR", "740"},
{"Svalbard and Jan Mayen", "Svalbard et l'Île Jan Mayen (le)", "SJ", "SJM", "744"},
{"Swaziland", "Swaziland (le)", "SZ", "SWZ", "748"},
{"Sweden", "Suède (la)", "SE", "SWE", "752"},
{"Switzerland", "Suisse (la)", "CH", "CHE", "756"},
{"Syrian Arab Republic", "République arabe syrienne (la)", "SY", "SYR", "760"},
{"Tajikistan", "Tadjikistan (le)", "TJ", "TJK", "762"},
{"Thailand", "Thaïlande (la)", "TH", "THA", "764"},
{"Togo", "Togo (le)", "TG", "TGO", "768"},
{"Tokelau", "Tokelau (les)", "TK", "TKL", "772"},
{"Tonga", "Tonga (les)", "TO", "TON", "776"},
{"Trinidad and Tobago", "Trinité-et-Tobago (la)", "TT", "TTO", "780"},
{"United Arab Emirates (the)", "Émirats arabes unis (les)", "AE", "ARE", "784"},
{"Tunisia", "Tunisie (la)", "TN", "TUN", "788"},
{"Turkey", "Turquie (la)", "TR", "TUR", "792"},
{"Turkmenistan", "Turkménistan (le)", "TM", "TKM", "795"},
{"Turks and Caicos Islands (the)", "Turks-et-Caïcos (les Îles)", "TC", "TCA", "796"},
{"Tuvalu", "Tuvalu (les)", "TV", "TUV", "798"},
{"Uganda", "Ouganda (l')", "UG", "UGA", "800"},
{"Ukraine", "Ukraine (l')", "UA", "UKR", "804"},
{"Macedonia (the former Yugoslav Republic of)", "Macédoine (l'exRépublique yougoslave de)", "MK", "MKD", "807"},
{"Egypt", "Égypte (l')", "EG", "EGY", "818"},
{"United Kingdom of Great Britain and Northern Ireland (the)", "Royaume-Uni de Grande-Bretagne et d'Irlande du Nord (le)", "GB", "GBR", "826"},
{"Guernsey", "Guernesey", "GG", "GGY", "831"},
{"Jersey", "Jersey", "JE", "JEY", "832"},
{"Isle of Man", "Île de Man", "IM", "IMN", "833"},
{"Tanzania, United Republic of", "Tanzanie, République-Unie de", "TZ", "TZA", "834"},
{"United States of America (the)", "États-Unis d'Amérique (les)", "US", "USA", "840"},
{"Virgin Islands (U.S.)", "Vierges des États-Unis (les Îles)", "VI", "VIR", "850"},
{"Burkina Faso", "Burkina Faso (le)", "BF", "BFA", "854"},
{"Uruguay", "Uruguay (l')", "UY", "URY", "858"},
{"Uzbekistan", "Ouzbékistan (l')", "UZ", "UZB", "860"},
{"Venezuela (Bolivarian Republic of)", "Venezuela (République bolivarienne du)", "VE", "VEN", "862"},
{"Wallis and Futuna", "Wallis-et-Futuna", "WF", "WLF", "876"},
{"Samoa", "Samoa (le)", "WS", "WSM", "882"},
{"Yemen", "Yémen (le)", "YE", "YEM", "887"},
{"Zambia", "Zambie (la)", "ZM", "ZMB", "894"},
}
// ISO4217List is the list of ISO currency codes
var ISO4217List = []string{
"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN",
"BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD",
"CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK",
"DJF", "DKK", "DOP", "DZD",
"EGP", "ERN", "ETB", "EUR",
"FJD", "FKP",
"GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
"HKD", "HNL", "HRK", "HTG", "HUF",
"IDR", "ILS", "INR", "IQD", "IRR", "ISK",
"JMD", "JOD", "JPY",
"KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT",
"LAK", "LBP", "LKR", "LRD", "LSL", "LYD",
"MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN",
"NAD", "NGN", "NIO", "NOK", "NPR", "NZD",
"OMR",
"PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG",
"QAR",
"RON", "RSD", "RUB", "RWF",
"SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP", "SZL",
"THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS",
"UAH", "UGX", "USD", "USN", "UYI", "UYU", "UZS",
"VEF", "VND", "VUV",
"WST",
"XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX",
"YER",
"ZAR", "ZMW", "ZWL",
}
// ISO693Entry stores ISO language codes
type ISO693Entry struct {
Alpha3bCode string
Alpha2Code string
English string
}
//ISO693List based on http://data.okfn.org/data/core/language-codes/r/language-codes-3b2.json
var ISO693List = []ISO693Entry{
{Alpha3bCode: "aar", Alpha2Code: "aa", English: "Afar"},
{Alpha3bCode: "abk", Alpha2Code: "ab", English: "Abkhazian"},
{Alpha3bCode: "afr", Alpha2Code: "af", English: "Afrikaans"},
{Alpha3bCode: "aka", Alpha2Code: "ak", English: "Akan"},
{Alpha3bCode: "alb", Alpha2Code: "sq", English: "Albanian"},
{Alpha3bCode: "amh", Alpha2Code: "am", English: "Amharic"},
{Alpha3bCode: "ara", Alpha2Code: "ar", English: "Arabic"},
{Alpha3bCode: "arg", Alpha2Code: "an", English: "Aragonese"},
{Alpha3bCode: "arm", Alpha2Code: "hy", English: "Armenian"},
{Alpha3bCode: "asm", Alpha2Code: "as", English: "Assamese"},
{Alpha3bCode: "ava", Alpha2Code: "av", English: "Avaric"},
{Alpha3bCode: "ave", Alpha2Code: "ae", English: "Avestan"},
{Alpha3bCode: "aym", Alpha2Code: "ay", English: "Aymara"},
{Alpha3bCode: "aze", Alpha2Code: "az", English: "Azerbaijani"},
{Alpha3bCode: "bak", Alpha2Code: "ba", English: "Bashkir"},
{Alpha3bCode: "bam", Alpha2Code: "bm", English: "Bambara"},
{Alpha3bCode: "baq", Alpha2Code: "eu", English: "Basque"},
{Alpha3bCode: "bel", Alpha2Code: "be", English: "Belarusian"},
{Alpha3bCode: "ben", Alpha2Code: "bn", English: "Bengali"},
{Alpha3bCode: "bih", Alpha2Code: "bh", English: "Bihari languages"},
{Alpha3bCode: "bis", Alpha2Code: "bi", English: "Bislama"},
{Alpha3bCode: "bos", Alpha2Code: "bs", English: "Bosnian"},
{Alpha3bCode: "bre", Alpha2Code: "br", English: "Breton"},
{Alpha3bCode: "bul", Alpha2Code: "bg", English: "Bulgarian"},
{Alpha3bCode: "bur", Alpha2Code: "my", English: "Burmese"},
{Alpha3bCode: "cat", Alpha2Code: "ca", English: "Catalan; Valencian"},
{Alpha3bCode: "cha", Alpha2Code: "ch", English: "Chamorro"},
{Alpha3bCode: "che", Alpha2Code: "ce", English: "Chechen"},
{Alpha3bCode: "chi", Alpha2Code: "zh", English: "Chinese"},
{Alpha3bCode: "chu", Alpha2Code: "cu", English: "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"},
{Alpha3bCode: "chv", Alpha2Code: "cv", English: "Chuvash"},
{Alpha3bCode: "cor", Alpha2Code: "kw", English: "Cornish"},
{Alpha3bCode: "cos", Alpha2Code: "co", English: "Corsican"},
{Alpha3bCode: "cre", Alpha2Code: "cr", English: "Cree"},
{Alpha3bCode: "cze", Alpha2Code: "cs", English: "Czech"},
{Alpha3bCode: "dan", Alpha2Code: "da", English: "Danish"},
{Alpha3bCode: "div", Alpha2Code: "dv", English: "Divehi; Dhivehi; Maldivian"},
{Alpha3bCode: "dut", Alpha2Code: "nl", English: "Dutch; Flemish"},
{Alpha3bCode: "dzo", Alpha2Code: "dz", English: "Dzongkha"},
{Alpha3bCode: "eng", Alpha2Code: "en", English: "English"},
{Alpha3bCode: "epo", Alpha2Code: "eo", English: "Esperanto"},
{Alpha3bCode: "est", Alpha2Code: "et", English: "Estonian"},
{Alpha3bCode: "ewe", Alpha2Code: "ee", English: "Ewe"},
{Alpha3bCode: "fao", Alpha2Code: "fo", English: "Faroese"},
{Alpha3bCode: "fij", Alpha2Code: "fj", English: "Fijian"},
{Alpha3bCode: "fin", Alpha2Code: "fi", English: "Finnish"},
{Alpha3bCode: "fre", Alpha2Code: "fr", English: "French"},
{Alpha3bCode: "fry", Alpha2Code: "fy", English: "Western Frisian"},
{Alpha3bCode: "ful", Alpha2Code: "ff", English: "Fulah"},
{Alpha3bCode: "geo", Alpha2Code: "ka", English: "Georgian"},
{Alpha3bCode: "ger", Alpha2Code: "de", English: "German"},
{Alpha3bCode: "gla", Alpha2Code: "gd", English: "Gaelic; Scottish Gaelic"},
{Alpha3bCode: "gle", Alpha2Code: "ga", English: "Irish"},
{Alpha3bCode: "glg", Alpha2Code: "gl", English: "Galician"},
{Alpha3bCode: "glv", Alpha2Code: "gv", English: "Manx"},
{Alpha3bCode: "gre", Alpha2Code: "el", English: "Greek, Modern (1453-)"},
{Alpha3bCode: "grn", Alpha2Code: "gn", English: "Guarani"},
{Alpha3bCode: "guj", Alpha2Code: "gu", English: "Gujarati"},
{Alpha3bCode: "hat", Alpha2Code: "ht", English: "Haitian; Haitian Creole"},
{Alpha3bCode: "hau", Alpha2Code: "ha", English: "Hausa"},
{Alpha3bCode: "heb", Alpha2Code: "he", English: "Hebrew"},
{Alpha3bCode: "her", Alpha2Code: "hz", English: "Herero"},
{Alpha3bCode: "hin", Alpha2Code: "hi", English: "Hindi"},
{Alpha3bCode: "hmo", Alpha2Code: "ho", English: "Hiri Motu"},
{Alpha3bCode: "hrv", Alpha2Code: "hr", English: "Croatian"},
{Alpha3bCode: "hun", Alpha2Code: "hu", English: "Hungarian"},
{Alpha3bCode: "ibo", Alpha2Code: "ig", English: "Igbo"},
{Alpha3bCode: "ice", Alpha2Code: "is", English: "Icelandic"},
{Alpha3bCode: "ido", Alpha2Code: "io", English: "Ido"},
{Alpha3bCode: "iii", Alpha2Code: "ii", English: "Sichuan Yi; Nuosu"},
{Alpha3bCode: "iku", Alpha2Code: "iu", English: "Inuktitut"},
{Alpha3bCode: "ile", Alpha2Code: "ie", English: "Interlingue; Occidental"},
{Alpha3bCode: "ina", Alpha2Code: "ia", English: "Interlingua (International Auxiliary Language Association)"},
{Alpha3bCode: "ind", Alpha2Code: "id", English: "Indonesian"},
{Alpha3bCode: "ipk", Alpha2Code: "ik", English: "Inupiaq"},
{Alpha3bCode: "ita", Alpha2Code: "it", English: "Italian"},
{Alpha3bCode: "jav", Alpha2Code: "jv", English: "Javanese"},
{Alpha3bCode: "jpn", Alpha2Code: "ja", English: "Japanese"},
{Alpha3bCode: "kal", Alpha2Code: "kl", English: "Kalaallisut; Greenlandic"},
{Alpha3bCode: "kan", Alpha2Code: "kn", English: "Kannada"},
{Alpha3bCode: "kas", Alpha2Code: "ks", English: "Kashmiri"},
{Alpha3bCode: "kau", Alpha2Code: "kr", English: "Kanuri"},
{Alpha3bCode: "kaz", Alpha2Code: "kk", English: "Kazakh"},
{Alpha3bCode: "khm", Alpha2Code: "km", English: "Central Khmer"},
{Alpha3bCode: "kik", Alpha2Code: "ki", English: "Kikuyu; Gikuyu"},
{Alpha3bCode: "kin", Alpha2Code: "rw", English: "Kinyarwanda"},
{Alpha3bCode: "kir", Alpha2Code: "ky", English: "Kirghiz; Kyrgyz"},
{Alpha3bCode: "kom", Alpha2Code: "kv", English: "Komi"},
{Alpha3bCode: "kon", Alpha2Code: "kg", English: "Kongo"},
{Alpha3bCode: "kor", Alpha2Code: "ko", English: "Korean"},
{Alpha3bCode: "kua", Alpha2Code: "kj", English: "Kuanyama; Kwanyama"},
{Alpha3bCode: "kur", Alpha2Code: "ku", English: "Kurdish"},
{Alpha3bCode: "lao", Alpha2Code: "lo", English: "Lao"},
{Alpha3bCode: "lat", Alpha2Code: "la", English: "Latin"},
{Alpha3bCode: "lav", Alpha2Code: "lv", English: "Latvian"},
{Alpha3bCode: "lim", Alpha2Code: "li", English: "Limburgan; Limburger; Limburgish"},
{Alpha3bCode: "lin", Alpha2Code: "ln", English: "Lingala"},
{Alpha3bCode: "lit", Alpha2Code: "lt", English: "Lithuanian"},
{Alpha3bCode: "ltz", Alpha2Code: "lb", English: "Luxembourgish; Letzeburgesch"},
{Alpha3bCode: "lub", Alpha2Code: "lu", English: "Luba-Katanga"},
{Alpha3bCode: "lug", Alpha2Code: "lg", English: "Ganda"},
{Alpha3bCode: "mac", Alpha2Code: "mk", English: "Macedonian"},
{Alpha3bCode: "mah", Alpha2Code: "mh", English: "Marshallese"},
{Alpha3bCode: "mal", Alpha2Code: "ml", English: "Malayalam"},
{Alpha3bCode: "mao", Alpha2Code: "mi", English: "Maori"},
{Alpha3bCode: "mar", Alpha2Code: "mr", English: "Marathi"},
{Alpha3bCode: "may", Alpha2Code: "ms", English: "Malay"},
{Alpha3bCode: "mlg", Alpha2Code: "mg", English: "Malagasy"},
{Alpha3bCode: "mlt", Alpha2Code: "mt", English: "Maltese"},
{Alpha3bCode: "mon", Alpha2Code: "mn", English: "Mongolian"},
{Alpha3bCode: "nau", Alpha2Code: "na", English: "Nauru"},
{Alpha3bCode: "nav", Alpha2Code: "nv", English: "Navajo; Navaho"},
{Alpha3bCode: "nbl", Alpha2Code: "nr", English: "Ndebele, South; South Ndebele"},
{Alpha3bCode: "nde", Alpha2Code: "nd", English: "Ndebele, North; North Ndebele"},
{Alpha3bCode: "ndo", Alpha2Code: "ng", English: "Ndonga"},
{Alpha3bCode: "nep", Alpha2Code: "ne", English: "Nepali"},
{Alpha3bCode: "nno", Alpha2Code: "nn", English: "Norwegian Nynorsk; Nynorsk, Norwegian"},
{Alpha3bCode: "nob", Alpha2Code: "nb", English: "Bokmål, Norwegian; Norwegian Bokmål"},
{Alpha3bCode: "nor", Alpha2Code: "no", English: "Norwegian"},
{Alpha3bCode: "nya", Alpha2Code: "ny", English: "Chichewa; Chewa; Nyanja"},
{Alpha3bCode: "oci", Alpha2Code: "oc", English: "Occitan (post 1500); Provençal"},
{Alpha3bCode: "oji", Alpha2Code: "oj", English: "Ojibwa"},
{Alpha3bCode: "ori", Alpha2Code: "or", English: "Oriya"},
{Alpha3bCode: "orm", Alpha2Code: "om", English: "Oromo"},
{Alpha3bCode: "oss", Alpha2Code: "os", English: "Ossetian; Ossetic"},
{Alpha3bCode: "pan", Alpha2Code: "pa", English: "Panjabi; Punjabi"},
{Alpha3bCode: "per", Alpha2Code: "fa", English: "Persian"},
{Alpha3bCode: "pli", Alpha2Code: "pi", English: "Pali"},
{Alpha3bCode: "pol", Alpha2Code: "pl", English: "Polish"},
{Alpha3bCode: "por", Alpha2Code: "pt", English: "Portuguese"},
{Alpha3bCode: "pus", Alpha2Code: "ps", English: "Pushto; Pashto"},
{Alpha3bCode: "que", Alpha2Code: "qu", English: "Quechua"},
{Alpha3bCode: "roh", Alpha2Code: "rm", English: "Romansh"},
{Alpha3bCode: "rum", Alpha2Code: "ro", English: "Romanian; Moldavian; Moldovan"},
{Alpha3bCode: "run", Alpha2Code: "rn", English: "Rundi"},
{Alpha3bCode: "rus", Alpha2Code: "ru", English: "Russian"},
{Alpha3bCode: "sag", Alpha2Code: "sg", English: "Sango"},
{Alpha3bCode: "san", Alpha2Code: "sa", English: "Sanskrit"},
{Alpha3bCode: "sin", Alpha2Code: "si", English: "Sinhala; Sinhalese"},
{Alpha3bCode: "slo", Alpha2Code: "sk", English: "Slovak"},
{Alpha3bCode: "slv", Alpha2Code: "sl", English: "Slovenian"},
{Alpha3bCode: "sme", Alpha2Code: "se", English: "Northern Sami"},
{Alpha3bCode: "smo", Alpha2Code: "sm", English: "Samoan"},
{Alpha3bCode: "sna", Alpha2Code: "sn", English: "Shona"},
{Alpha3bCode: "snd", Alpha2Code: "sd", English: "Sindhi"},
{Alpha3bCode: "som", Alpha2Code: "so", English: "Somali"},
{Alpha3bCode: "sot", Alpha2Code: "st", English: "Sotho, Southern"},
{Alpha3bCode: "spa", Alpha2Code: "es", English: "Spanish; Castilian"},
{Alpha3bCode: "srd", Alpha2Code: "sc", English: "Sardinian"},
{Alpha3bCode: "srp", Alpha2Code: "sr", English: "Serbian"},
{Alpha3bCode: "ssw", Alpha2Code: "ss", English: "Swati"},
{Alpha3bCode: "sun", Alpha2Code: "su", English: "Sundanese"},
{Alpha3bCode: "swa", Alpha2Code: "sw", English: "Swahili"},
{Alpha3bCode: "swe", Alpha2Code: "sv", English: "Swedish"},
{Alpha3bCode: "tah", Alpha2Code: "ty", English: "Tahitian"},
{Alpha3bCode: "tam", Alpha2Code: "ta", English: "Tamil"},
{Alpha3bCode: "tat", Alpha2Code: "tt", English: "Tatar"},
{Alpha3bCode: "tel", Alpha2Code: "te", English: "Telugu"},
{Alpha3bCode: "tgk", Alpha2Code: "tg", English: "Tajik"},
{Alpha3bCode: "tgl", Alpha2Code: "tl", English: "Tagalog"},
{Alpha3bCode: "tha", Alpha2Code: "th", English: "Thai"},
{Alpha3bCode: "tib", Alpha2Code: "bo", English: "Tibetan"},
{Alpha3bCode: "tir", Alpha2Code: "ti", English: "Tigrinya"},
{Alpha3bCode: "ton", Alpha2Code: "to", English: "Tonga (Tonga Islands)"},
{Alpha3bCode: "tsn", Alpha2Code: "tn", English: "Tswana"},
{Alpha3bCode: "tso", Alpha2Code: "ts", English: "Tsonga"},
{Alpha3bCode: "tuk", Alpha2Code: "tk", English: "Turkmen"},
{Alpha3bCode: "tur", Alpha2Code: "tr", English: "Turkish"},
{Alpha3bCode: "twi", Alpha2Code: "tw", English: "Twi"},
{Alpha3bCode: "uig", Alpha2Code: "ug", English: "Uighur; Uyghur"},
{Alpha3bCode: "ukr", Alpha2Code: "uk", English: "Ukrainian"},
{Alpha3bCode: "urd", Alpha2Code: "ur", English: "Urdu"},
{Alpha3bCode: "uzb", Alpha2Code: "uz", English: "Uzbek"},
{Alpha3bCode: "ven", Alpha2Code: "ve", English: "Venda"},
{Alpha3bCode: "vie", Alpha2Code: "vi", English: "Vietnamese"},
{Alpha3bCode: "vol", Alpha2Code: "vo", English: "Volapük"},
{Alpha3bCode: "wel", Alpha2Code: "cy", English: "Welsh"},
{Alpha3bCode: "wln", Alpha2Code: "wa", English: "Walloon"},
{Alpha3bCode: "wol", Alpha2Code: "wo", English: "Wolof"},
{Alpha3bCode: "xho", Alpha2Code: "xh", English: "Xhosa"},
{Alpha3bCode: "yid", Alpha2Code: "yi", English: "Yiddish"},
{Alpha3bCode: "yor", Alpha2Code: "yo", English: "Yoruba"},
{Alpha3bCode: "zha", Alpha2Code: "za", English: "Zhuang; Chuang"},
{Alpha3bCode: "zul", Alpha2Code: "zu", English: "Zulu"},
}

264
vendor/github.com/asaskevich/govalidator/utils.go generated vendored Normal file
View File

@@ -0,0 +1,264 @@
package govalidator
import (
"errors"
"fmt"
"html"
"math"
"path"
"regexp"
"strings"
"unicode"
"unicode/utf8"
)
// Contains check if the string contains the substring.
func Contains(str, substring string) bool {
return strings.Contains(str, substring)
}
// Matches check if string matches the pattern (pattern is regular expression)
// In case of error return false
func Matches(str, pattern string) bool {
match, _ := regexp.MatchString(pattern, str)
return match
}
// LeftTrim trim characters from the left-side of the input.
// If second argument is empty, it's will be remove leading spaces.
func LeftTrim(str, chars string) string {
if chars == "" {
return strings.TrimLeftFunc(str, unicode.IsSpace)
}
r, _ := regexp.Compile("^[" + chars + "]+")
return r.ReplaceAllString(str, "")
}
// RightTrim trim characters from the right-side of the input.
// If second argument is empty, it's will be remove spaces.
func RightTrim(str, chars string) string {
if chars == "" {
return strings.TrimRightFunc(str, unicode.IsSpace)
}
r, _ := regexp.Compile("[" + chars + "]+$")
return r.ReplaceAllString(str, "")
}
// Trim trim characters from both sides of the input.
// If second argument is empty, it's will be remove spaces.
func Trim(str, chars string) string {
return LeftTrim(RightTrim(str, chars), chars)
}
// WhiteList remove characters that do not appear in the whitelist.
func WhiteList(str, chars string) string {
pattern := "[^" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
// BlackList remove characters that appear in the blacklist.
func BlackList(str, chars string) string {
pattern := "[" + chars + "]+"
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, "")
}
// StripLow remove characters with a numerical value < 32 and 127, mostly control characters.
// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
func StripLow(str string, keepNewLines bool) string {
chars := ""
if keepNewLines {
chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
} else {
chars = "\x00-\x1F\x7F"
}
return BlackList(str, chars)
}
// ReplacePattern replace regular expression pattern in string
func ReplacePattern(str, pattern, replace string) string {
r, _ := regexp.Compile(pattern)
return r.ReplaceAllString(str, replace)
}
// Escape replace <, >, & and " with HTML entities.
var Escape = html.EscapeString
func addSegment(inrune, segment []rune) []rune {
if len(segment) == 0 {
return inrune
}
if len(inrune) != 0 {
inrune = append(inrune, '_')
}
inrune = append(inrune, segment...)
return inrune
}
// UnderscoreToCamelCase converts from underscore separated form to camel case form.
// Ex.: my_func => MyFunc
func UnderscoreToCamelCase(s string) string {
return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
}
// CamelCaseToUnderscore converts from camel case form to underscore separated form.
// Ex.: MyFunc => my_func
func CamelCaseToUnderscore(str string) string {
var output []rune
var segment []rune
for _, r := range str {
// not treat number as separate segment
if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) {
output = addSegment(output, segment)
segment = nil
}
segment = append(segment, unicode.ToLower(r))
}
output = addSegment(output, segment)
return string(output)
}
// Reverse return reversed string
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
// GetLines split string by "\n" and return array of lines
func GetLines(s string) []string {
return strings.Split(s, "\n")
}
// GetLine return specified line of multiline string
func GetLine(s string, index int) (string, error) {
lines := GetLines(s)
if index < 0 || index >= len(lines) {
return "", errors.New("line index out of bounds")
}
return lines[index], nil
}
// RemoveTags remove all tags from HTML string
func RemoveTags(s string) string {
return ReplacePattern(s, "<[^>]*>", "")
}
// SafeFileName return safe string that can be used in file names
func SafeFileName(str string) string {
name := strings.ToLower(str)
name = path.Clean(path.Base(name))
name = strings.Trim(name, " ")
separators, err := regexp.Compile(`[ &_=+:]`)
if err == nil {
name = separators.ReplaceAllString(name, "-")
}
legal, err := regexp.Compile(`[^[:alnum:]-.]`)
if err == nil {
name = legal.ReplaceAllString(name, "")
}
for strings.Contains(name, "--") {
name = strings.Replace(name, "--", "-", -1)
}
return name
}
// NormalizeEmail canonicalize an email address.
// The local part of the email address is lowercased for all domains; the hostname is always lowercased and
// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
// normalized to @gmail.com.
func NormalizeEmail(str string) (string, error) {
if !IsEmail(str) {
return "", fmt.Errorf("%s is not an email", str)
}
parts := strings.Split(str, "@")
parts[0] = strings.ToLower(parts[0])
parts[1] = strings.ToLower(parts[1])
if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
parts[1] = "gmail.com"
parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
}
return strings.Join(parts, "@"), nil
}
// Truncate a string to the closest length without breaking words.
func Truncate(str string, length int, ending string) string {
var aftstr, befstr string
if len(str) > length {
words := strings.Fields(str)
before, present := 0, 0
for i := range words {
befstr = aftstr
before = present
aftstr = aftstr + words[i] + " "
present = len(aftstr)
if present > length && i != 0 {
if (length - before) < (present - length) {
return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
}
return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
}
}
}
return str
}
// PadLeft pad left side of string if size of string is less then indicated pad length
func PadLeft(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, false)
}
// PadRight pad right side of string if size of string is less then indicated pad length
func PadRight(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, false, true)
}
// PadBoth pad sides of string if size of string is less then indicated pad length
func PadBoth(str string, padStr string, padLen int) string {
return buildPadStr(str, padStr, padLen, true, true)
}
// PadString either left, right or both sides, not the padding string can be unicode and more then one
// character
func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
// When padded length is less then the current string size
if padLen < utf8.RuneCountInString(str) {
return str
}
padLen -= utf8.RuneCountInString(str)
targetLen := padLen
targetLenLeft := targetLen
targetLenRight := targetLen
if padLeft && padRight {
targetLenLeft = padLen / 2
targetLenRight = padLen - targetLenLeft
}
strToRepeatLen := utf8.RuneCountInString(padStr)
repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen)))
repeatedString := strings.Repeat(padStr, repeatTimes)
leftSide := ""
if padLeft {
leftSide = repeatedString[0:targetLenLeft]
}
rightSide := ""
if padRight {
rightSide = repeatedString[0:targetLenRight]
}
return leftSide + str + rightSide
}

1213
vendor/github.com/asaskevich/govalidator/validator.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

21
vendor/github.com/fatih/structs/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Fatih Arslan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

141
vendor/github.com/fatih/structs/field.go generated vendored Normal file
View File

@@ -0,0 +1,141 @@
package structs
import (
"errors"
"fmt"
"reflect"
)
var (
errNotExported = errors.New("field is not exported")
errNotSettable = errors.New("field is not settable")
)
// Field represents a single struct field that encapsulates high level
// functions around the field.
type Field struct {
value reflect.Value
field reflect.StructField
defaultTag string
}
// Tag returns the value associated with key in the tag string. If there is no
// such key in the tag, Tag returns the empty string.
func (f *Field) Tag(key string) string {
return f.field.Tag.Get(key)
}
// Value returns the underlying value of the field. It panics if the field
// is not exported.
func (f *Field) Value() interface{} {
return f.value.Interface()
}
// IsEmbedded returns true if the given field is an anonymous field (embedded)
func (f *Field) IsEmbedded() bool {
return f.field.Anonymous
}
// IsExported returns true if the given field is exported.
func (f *Field) IsExported() bool {
return f.field.PkgPath == ""
}
// IsZero returns true if the given field is not initialized (has a zero value).
// It panics if the field is not exported.
func (f *Field) IsZero() bool {
zero := reflect.Zero(f.value.Type()).Interface()
current := f.Value()
return reflect.DeepEqual(current, zero)
}
// Name returns the name of the given field
func (f *Field) Name() string {
return f.field.Name
}
// Kind returns the fields kind, such as "string", "map", "bool", etc ..
func (f *Field) Kind() reflect.Kind {
return f.value.Kind()
}
// Set sets the field to given value v. It returns an error if the field is not
// settable (not addressable or not exported) or if the given value's type
// doesn't match the fields type.
func (f *Field) Set(val interface{}) error {
// we can't set unexported fields, so be sure this field is exported
if !f.IsExported() {
return errNotExported
}
// do we get here? not sure...
if !f.value.CanSet() {
return errNotSettable
}
given := reflect.ValueOf(val)
if f.value.Kind() != given.Kind() {
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
}
f.value.Set(given)
return nil
}
// Zero sets the field to its zero value. It returns an error if the field is not
// settable (not addressable or not exported).
func (f *Field) Zero() error {
zero := reflect.Zero(f.value.Type()).Interface()
return f.Set(zero)
}
// Fields returns a slice of Fields. This is particular handy to get the fields
// of a nested struct . A struct tag with the content of "-" ignores the
// checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field *http.Request `structs:"-"`
//
// It panics if field is not exported or if field's kind is not struct
func (f *Field) Fields() []*Field {
return getFields(f.value, f.defaultTag)
}
// Field returns the field from a nested struct. It panics if the nested struct
// is not exported or if the field was not found.
func (f *Field) Field(name string) *Field {
field, ok := f.FieldOk(name)
if !ok {
panic("field not found")
}
return field
}
// FieldOk returns the field from a nested struct. The boolean returns whether
// the field was found (true) or not (false).
func (f *Field) FieldOk(name string) (*Field, bool) {
value := &f.value
// value must be settable so we need to make sure it holds the address of the
// variable and not a copy, so we can pass the pointer to strctVal instead of a
// copy (which is not assigned to any variable, hence not settable).
// see "https://blog.golang.org/laws-of-reflection#TOC_8."
if f.value.Kind() != reflect.Ptr {
a := f.value.Addr()
value = &a
}
v := strctVal(value.Interface())
t := v.Type()
field, ok := t.FieldByName(name)
if !ok {
return nil, false
}
return &Field{
field: field,
value: v.FieldByName(name),
}, true
}

584
vendor/github.com/fatih/structs/structs.go generated vendored Normal file
View File

@@ -0,0 +1,584 @@
// Package structs contains various utilities functions to work with structs.
package structs
import (
"fmt"
"reflect"
)
var (
// DefaultTagName is the default tag name for struct fields which provides
// a more granular to tweak certain structs. Lookup the necessary functions
// for more info.
DefaultTagName = "structs" // struct's field default tag name
)
// Struct encapsulates a struct type to provide several high level functions
// around the struct.
type Struct struct {
raw interface{}
value reflect.Value
TagName string
}
// New returns a new *Struct with the struct s. It panics if the s's kind is
// not struct.
func New(s interface{}) *Struct {
return &Struct{
raw: s,
value: strctVal(s),
TagName: DefaultTagName,
}
}
// Map converts the given struct to a map[string]interface{}, where the keys
// of the map are the field names and the values of the map the associated
// values of the fields. The default key string is the struct field name but
// can be changed in the struct field's tag value. The "structs" key in the
// struct's field tag value is the key name. Example:
//
// // Field appears in map as key "myName".
// Name string `structs:"myName"`
//
// A tag value with the content of "-" ignores that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A tag value with the content of "string" uses the stringer to get the value. Example:
//
// // The value will be output of Animal's String() func.
// // Map will panic if Animal does not implement String().
// Field *Animal `structs:"field,string"`
//
// A tag value with the option of "flatten" used in a struct field is to flatten its fields
// in the output map. Example:
//
// // The FieldStruct's fields will be flattened into the output map.
// FieldStruct time.Time `structs:",flatten"`
//
// A tag value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// A tag value with the option of "omitempty" ignores that particular field if
// the field value is empty. Example:
//
// // Field appears in map as key "myName", but the field is
// // skipped if empty.
// Field string `structs:"myName,omitempty"`
//
// // Field appears in map as key "Field" (the default), but
// // the field is skipped if empty.
// Field string `structs:",omitempty"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected.
func (s *Struct) Map() map[string]interface{} {
out := make(map[string]interface{})
s.FillMap(out)
return out
}
// FillMap is the same as Map. Instead of returning the output, it fills the
// given map.
func (s *Struct) FillMap(out map[string]interface{}) {
if out == nil {
return
}
fields := s.structFields()
for _, field := range fields {
name := field.Name
val := s.value.FieldByName(name)
isSubStruct := false
var finalVal interface{}
tagName, tagOpts := parseTag(field.Tag.Get(s.TagName))
if tagName != "" {
name = tagName
}
// if the value is a zero value and the field is marked as omitempty do
// not include
if tagOpts.Has("omitempty") {
zero := reflect.Zero(val.Type()).Interface()
current := val.Interface()
if reflect.DeepEqual(current, zero) {
continue
}
}
if !tagOpts.Has("omitnested") {
finalVal = s.nested(val)
v := reflect.ValueOf(val.Interface())
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
case reflect.Map, reflect.Struct:
isSubStruct = true
}
} else {
finalVal = val.Interface()
}
if tagOpts.Has("string") {
s, ok := val.Interface().(fmt.Stringer)
if ok {
out[name] = s.String()
}
continue
}
if isSubStruct && (tagOpts.Has("flatten")) {
for k := range finalVal.(map[string]interface{}) {
out[k] = finalVal.(map[string]interface{})[k]
}
} else {
out[name] = finalVal
}
}
}
// Values converts the given s struct's field values to a []interface{}. A
// struct tag with the content of "-" ignores the that particular field.
// Example:
//
// // Field is ignored by this package.
// Field int `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Fields is not processed further by this package.
// Field time.Time `structs:",omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// A tag value with the option of "omitempty" ignores that particular field and
// is not added to the values if the field value is empty. Example:
//
// // Field is skipped if empty
// Field string `structs:",omitempty"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected.
func (s *Struct) Values() []interface{} {
fields := s.structFields()
var t []interface{}
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
// if the value is a zero value and the field is marked as omitempty do
// not include
if tagOpts.Has("omitempty") {
zero := reflect.Zero(val.Type()).Interface()
current := val.Interface()
if reflect.DeepEqual(current, zero) {
continue
}
}
if tagOpts.Has("string") {
s, ok := val.Interface().(fmt.Stringer)
if ok {
t = append(t, s.String())
}
continue
}
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
// look out for embedded structs, and convert them to a
// []interface{} to be added to the final values slice
t = append(t, Values(val.Interface())...)
} else {
t = append(t, val.Interface())
}
}
return t
}
// Fields returns a slice of Fields. A struct tag with the content of "-"
// ignores the checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// It panics if s's kind is not struct.
func (s *Struct) Fields() []*Field {
return getFields(s.value, s.TagName)
}
// Names returns a slice of field names. A struct tag with the content of "-"
// ignores the checking of that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// It panics if s's kind is not struct.
func (s *Struct) Names() []string {
fields := getFields(s.value, s.TagName)
names := make([]string, len(fields))
for i, field := range fields {
names[i] = field.Name()
}
return names
}
func getFields(v reflect.Value, tagName string) []*Field {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
t := v.Type()
var fields []*Field
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if tag := field.Tag.Get(tagName); tag == "-" {
continue
}
f := &Field{
field: field,
value: v.FieldByName(field.Name),
}
fields = append(fields, f)
}
return fields
}
// Field returns a new Field struct that provides several high level functions
// around a single struct field entity. It panics if the field is not found.
func (s *Struct) Field(name string) *Field {
f, ok := s.FieldOk(name)
if !ok {
panic("field not found")
}
return f
}
// FieldOk returns a new Field struct that provides several high level functions
// around a single struct field entity. The boolean returns true if the field
// was found.
func (s *Struct) FieldOk(name string) (*Field, bool) {
t := s.value.Type()
field, ok := t.FieldByName(name)
if !ok {
return nil, false
}
return &Field{
field: field,
value: s.value.FieldByName(name),
defaultTag: s.TagName,
}, true
}
// IsZero returns true if all fields in a struct is a zero value (not
// initialized) A struct tag with the content of "-" ignores the checking of
// that particular field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected. It panics if s's kind is not struct.
func (s *Struct) IsZero() bool {
fields := s.structFields()
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := IsZero(val.Interface())
if !ok {
return false
}
continue
}
// zero value of the given field, such as "" for string, 0 for int
zero := reflect.Zero(val.Type()).Interface()
// current value of the given field
current := val.Interface()
if !reflect.DeepEqual(current, zero) {
return false
}
}
return true
}
// HasZero returns true if a field in a struct is not initialized (zero value).
// A struct tag with the content of "-" ignores the checking of that particular
// field. Example:
//
// // Field is ignored by this package.
// Field bool `structs:"-"`
//
// A value with the option of "omitnested" stops iterating further if the type
// is a struct. Example:
//
// // Field is not processed further by this package.
// Field time.Time `structs:"myName,omitnested"`
// Field *http.Request `structs:",omitnested"`
//
// Note that only exported fields of a struct can be accessed, non exported
// fields will be neglected. It panics if s's kind is not struct.
func (s *Struct) HasZero() bool {
fields := s.structFields()
for _, field := range fields {
val := s.value.FieldByName(field.Name)
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
ok := HasZero(val.Interface())
if ok {
return true
}
continue
}
// zero value of the given field, such as "" for string, 0 for int
zero := reflect.Zero(val.Type()).Interface()
// current value of the given field
current := val.Interface()
if reflect.DeepEqual(current, zero) {
return true
}
}
return false
}
// Name returns the structs's type name within its package. For more info refer
// to Name() function.
func (s *Struct) Name() string {
return s.value.Type().Name()
}
// structFields returns the exported struct fields for a given s struct. This
// is a convenient helper method to avoid duplicate code in some of the
// functions.
func (s *Struct) structFields() []reflect.StructField {
t := s.value.Type()
var f []reflect.StructField
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
// we can't access the value of unexported fields
if field.PkgPath != "" {
continue
}
// don't check if it's omitted
if tag := field.Tag.Get(s.TagName); tag == "-" {
continue
}
f = append(f, field)
}
return f
}
func strctVal(s interface{}) reflect.Value {
v := reflect.ValueOf(s)
// if pointer get the underlying element≤
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
panic("not struct")
}
return v
}
// Map converts the given struct to a map[string]interface{}. For more info
// refer to Struct types Map() method. It panics if s's kind is not struct.
func Map(s interface{}) map[string]interface{} {
return New(s).Map()
}
// FillMap is the same as Map. Instead of returning the output, it fills the
// given map.
func FillMap(s interface{}, out map[string]interface{}) {
New(s).FillMap(out)
}
// Values converts the given struct to a []interface{}. For more info refer to
// Struct types Values() method. It panics if s's kind is not struct.
func Values(s interface{}) []interface{} {
return New(s).Values()
}
// Fields returns a slice of *Field. For more info refer to Struct types
// Fields() method. It panics if s's kind is not struct.
func Fields(s interface{}) []*Field {
return New(s).Fields()
}
// Names returns a slice of field names. For more info refer to Struct types
// Names() method. It panics if s's kind is not struct.
func Names(s interface{}) []string {
return New(s).Names()
}
// IsZero returns true if all fields is equal to a zero value. For more info
// refer to Struct types IsZero() method. It panics if s's kind is not struct.
func IsZero(s interface{}) bool {
return New(s).IsZero()
}
// HasZero returns true if any field is equal to a zero value. For more info
// refer to Struct types HasZero() method. It panics if s's kind is not struct.
func HasZero(s interface{}) bool {
return New(s).HasZero()
}
// IsStruct returns true if the given variable is a struct or a pointer to
// struct.
func IsStruct(s interface{}) bool {
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// uninitialized zero value of a struct
if v.Kind() == reflect.Invalid {
return false
}
return v.Kind() == reflect.Struct
}
// Name returns the structs's type name within its package. It returns an
// empty string for unnamed types. It panics if s's kind is not struct.
func Name(s interface{}) string {
return New(s).Name()
}
// nested retrieves recursively all types for the given value and returns the
// nested value.
func (s *Struct) nested(val reflect.Value) interface{} {
var finalVal interface{}
v := reflect.ValueOf(val.Interface())
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
case reflect.Struct:
n := New(val.Interface())
n.TagName = s.TagName
m := n.Map()
// do not add the converted value if there are no exported fields, ie:
// time.Time
if len(m) == 0 {
finalVal = val.Interface()
} else {
finalVal = m
}
case reflect.Map:
// get the element type of the map
mapElem := val.Type()
switch val.Type().Kind() {
case reflect.Ptr, reflect.Array, reflect.Map,
reflect.Slice, reflect.Chan:
mapElem = val.Type().Elem()
if mapElem.Kind() == reflect.Ptr {
mapElem = mapElem.Elem()
}
}
// only iterate over struct types, ie: map[string]StructType,
// map[string][]StructType,
if mapElem.Kind() == reflect.Struct ||
(mapElem.Kind() == reflect.Slice &&
mapElem.Elem().Kind() == reflect.Struct) {
m := make(map[string]interface{}, val.Len())
for _, k := range val.MapKeys() {
m[k.String()] = s.nested(val.MapIndex(k))
}
finalVal = m
break
}
// TODO(arslan): should this be optional?
finalVal = val.Interface()
case reflect.Slice, reflect.Array:
if val.Type().Kind() == reflect.Interface {
finalVal = val.Interface()
break
}
// TODO(arslan): should this be optional?
// do not iterate of non struct types, just pass the value. Ie: []int,
// []string, co... We only iterate further if it's a struct.
// i.e []foo or []*foo
if val.Type().Elem().Kind() != reflect.Struct &&
!(val.Type().Elem().Kind() == reflect.Ptr &&
val.Type().Elem().Elem().Kind() == reflect.Struct) {
finalVal = val.Interface()
break
}
slices := make([]interface{}, val.Len())
for x := 0; x < val.Len(); x++ {
slices[x] = s.nested(val.Index(x))
}
finalVal = slices
default:
finalVal = val.Interface()
}
return finalVal
}

32
vendor/github.com/fatih/structs/tags.go generated vendored Normal file
View File

@@ -0,0 +1,32 @@
package structs
import "strings"
// tagOptions contains a slice of tag options
type tagOptions []string
// Has returns true if the given option is available in tagOptions
func (t tagOptions) Has(opt string) bool {
for _, tagOpt := range t {
if tagOpt == opt {
return true
}
}
return false
}
// parseTag splits a struct field's tag into its name and a list of options
// which comes after a name. A tag is in the form of: "name,option1,option2".
// The name can be neglectected.
func parseTag(tag string) (string, tagOptions) {
// tag is one of followings:
// ""
// "name"
// "name,opt"
// "name,opt,opt2"
// ",opt"
res := strings.Split(tag, ",")
return res[0], res[1:]
}

20
vendor/github.com/gocraft/dbr/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014-2017 Jonathan Novak, Tai-Lin Chu
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

29
vendor/github.com/gocraft/dbr/buffer.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
package dbr
import "bytes"
type Buffer interface {
WriteString(s string) (n int, err error)
String() string
WriteValue(v ...interface{}) (err error)
Value() []interface{}
}
type buffer struct {
bytes.Buffer
v []interface{}
}
func NewBuffer() Buffer {
return &buffer{}
}
func (b *buffer) WriteValue(v ...interface{}) error {
b.v = append(b.v, v...)
return nil
}
func (b *buffer) Value() []interface{} {
return b.v
}

13
vendor/github.com/gocraft/dbr/builder.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
package dbr
// Builder builds sql in one dialect like MySQL/PostgreSQL
// e.g. XxxBuilder
type Builder interface {
Build(Dialect, Buffer) error
}
type BuildFunc func(Dialect, Buffer) error
func (b BuildFunc) Build(d Dialect, buf Buffer) error {
return b(d, buf)
}

119
vendor/github.com/gocraft/dbr/condition.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
package dbr
import "reflect"
func buildCond(d Dialect, buf Buffer, pred string, cond ...Builder) error {
for i, c := range cond {
if i > 0 {
buf.WriteString(" ")
buf.WriteString(pred)
buf.WriteString(" ")
}
buf.WriteString("(")
err := c.Build(d, buf)
if err != nil {
return err
}
buf.WriteString(")")
}
return nil
}
// And creates AND from a list of conditions
func And(cond ...Builder) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCond(d, buf, "AND", cond...)
})
}
// Or creates OR from a list of conditions
func Or(cond ...Builder) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCond(d, buf, "OR", cond...)
})
}
func buildCmp(d Dialect, buf Buffer, pred string, column string, value interface{}) error {
buf.WriteString(d.QuoteIdent(column))
buf.WriteString(" ")
buf.WriteString(pred)
buf.WriteString(" ")
buf.WriteString(placeholder)
buf.WriteValue(value)
return nil
}
// Eq is `=`.
// When value is nil, it will be translated to `IS NULL`.
// When value is a slice, it will be translated to `IN`.
// Otherwise it will be translated to `=`.
func Eq(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
if value == nil {
buf.WriteString(d.QuoteIdent(column))
buf.WriteString(" IS NULL")
return nil
}
v := reflect.ValueOf(value)
if v.Kind() == reflect.Slice {
if v.Len() == 0 {
buf.WriteString(d.EncodeBool(false))
return nil
}
return buildCmp(d, buf, "IN", column, value)
}
return buildCmp(d, buf, "=", column, value)
})
}
// Neq is `!=`.
// When value is nil, it will be translated to `IS NOT NULL`.
// When value is a slice, it will be translated to `NOT IN`.
// Otherwise it will be translated to `!=`.
func Neq(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
if value == nil {
buf.WriteString(d.QuoteIdent(column))
buf.WriteString(" IS NOT NULL")
return nil
}
v := reflect.ValueOf(value)
if v.Kind() == reflect.Slice {
if v.Len() == 0 {
buf.WriteString(d.EncodeBool(true))
return nil
}
return buildCmp(d, buf, "NOT IN", column, value)
}
return buildCmp(d, buf, "!=", column, value)
})
}
// Gt is `>`.
func Gt(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCmp(d, buf, ">", column, value)
})
}
// Gte is '>='.
func Gte(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCmp(d, buf, ">=", column, value)
})
}
// Lt is '<'.
func Lt(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCmp(d, buf, "<", column, value)
})
}
// Lte is `<=`.
func Lte(column string, value interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
return buildCmp(d, buf, "<=", column, value)
})
}

174
vendor/github.com/gocraft/dbr/dbr.go generated vendored Normal file
View File

@@ -0,0 +1,174 @@
package dbr
import (
"context"
"database/sql"
"fmt"
"time"
"github.com/gocraft/dbr/dialect"
)
// Open instantiates a Connection for a given database/sql connection
// and event receiver
func Open(driver, dsn string, log EventReceiver) (*Connection, error) {
if log == nil {
log = nullReceiver
}
conn, err := sql.Open(driver, dsn)
if err != nil {
return nil, err
}
var d Dialect
switch driver {
case "mysql":
d = dialect.MySQL
case "postgres":
d = dialect.PostgreSQL
case "sqlite3":
d = dialect.SQLite3
default:
return nil, ErrNotSupported
}
return &Connection{DB: conn, EventReceiver: log, Dialect: d}, nil
}
const (
placeholder = "?"
)
// Connection is a connection to the database with an EventReceiver
// to send events, errors, and timings to
type Connection struct {
*sql.DB
Dialect Dialect
EventReceiver
}
// Session represents a business unit of execution for some connection
type Session struct {
*Connection
EventReceiver
Timeout time.Duration
}
func (s *Session) GetTimeout() time.Duration {
return s.Timeout
}
// NewSession instantiates a Session for the Connection
func (conn *Connection) NewSession(log EventReceiver) *Session {
if log == nil {
log = conn.EventReceiver // Use parent instrumentation
}
return &Session{Connection: conn, EventReceiver: log}
}
// Ensure that tx and session are session runner
var (
_ SessionRunner = (*Tx)(nil)
_ SessionRunner = (*Session)(nil)
)
// SessionRunner can do anything that a Session can except start a transaction.
type SessionRunner interface {
Select(column ...string) *SelectBuilder
SelectBySql(query string, value ...interface{}) *SelectBuilder
InsertInto(table string) *InsertBuilder
InsertBySql(query string, value ...interface{}) *InsertBuilder
Update(table string) *UpdateBuilder
UpdateBySql(query string, value ...interface{}) *UpdateBuilder
DeleteFrom(table string) *DeleteBuilder
DeleteBySql(query string, value ...interface{}) *DeleteBuilder
}
type runner interface {
GetTimeout() time.Duration
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
}
func exec(ctx context.Context, runner runner, log EventReceiver, builder Builder, d Dialect) (sql.Result, error) {
timeout := runner.GetTimeout()
if timeout > 0 {
var cancel func()
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
i := interpolator{
Buffer: NewBuffer(),
Dialect: d,
IgnoreBinary: true,
}
err := i.interpolate(placeholder, []interface{}{builder})
query, value := i.String(), i.Value()
if err != nil {
return nil, log.EventErrKv("dbr.exec.interpolate", err, kvs{
"sql": query,
"args": fmt.Sprint(value),
})
}
startTime := time.Now()
defer func() {
log.TimingKv("dbr.exec", time.Since(startTime).Nanoseconds(), kvs{
"sql": query,
})
}()
result, err := runner.ExecContext(ctx, query, value...)
if err != nil {
return result, log.EventErrKv("dbr.exec.exec", err, kvs{
"sql": query,
})
}
return result, nil
}
func query(ctx context.Context, runner runner, log EventReceiver, builder Builder, d Dialect, dest interface{}) (int, error) {
timeout := runner.GetTimeout()
if timeout > 0 {
var cancel func()
ctx, cancel = context.WithTimeout(ctx, timeout)
defer cancel()
}
i := interpolator{
Buffer: NewBuffer(),
Dialect: d,
IgnoreBinary: true,
}
err := i.interpolate(placeholder, []interface{}{builder})
query, value := i.String(), i.Value()
if err != nil {
return 0, log.EventErrKv("dbr.select.interpolate", err, kvs{
"sql": query,
"args": fmt.Sprint(value),
})
}
startTime := time.Now()
defer func() {
log.TimingKv("dbr.select", time.Since(startTime).Nanoseconds(), kvs{
"sql": query,
})
}()
rows, err := runner.QueryContext(ctx, query, value...)
if err != nil {
return 0, log.EventErrKv("dbr.select.load.query", err, kvs{
"sql": query,
})
}
count, err := Load(rows, dest)
if err != nil {
return 0, log.EventErrKv("dbr.select.load.scan", err, kvs{
"sql": query,
})
}
return count, nil
}

61
vendor/github.com/gocraft/dbr/delete.go generated vendored Normal file
View File

@@ -0,0 +1,61 @@
package dbr
// DeleteStmt builds `DELETE ...`
type DeleteStmt struct {
raw
Table string
WhereCond []Builder
}
// Build builds `DELETE ...` in dialect
func (b *DeleteStmt) Build(d Dialect, buf Buffer) error {
if b.raw.Query != "" {
return b.raw.Build(d, buf)
}
if b.Table == "" {
return ErrTableNotSpecified
}
buf.WriteString("DELETE FROM ")
buf.WriteString(d.QuoteIdent(b.Table))
if len(b.WhereCond) > 0 {
buf.WriteString(" WHERE ")
err := And(b.WhereCond...).Build(d, buf)
if err != nil {
return err
}
}
return nil
}
// DeleteFrom creates a DeleteStmt
func DeleteFrom(table string) *DeleteStmt {
return &DeleteStmt{
Table: table,
}
}
// DeleteBySql creates a DeleteStmt from raw query
func DeleteBySql(query string, value ...interface{}) *DeleteStmt {
return &DeleteStmt{
raw: raw{
Query: query,
Value: value,
},
}
}
// Where adds a where condition
func (b *DeleteStmt) Where(query interface{}, value ...interface{}) *DeleteStmt {
switch query := query.(type) {
case string:
b.WhereCond = append(b.WhereCond, Expr(query, value...))
case Builder:
b.WhereCond = append(b.WhereCond, query)
}
return b
}

87
vendor/github.com/gocraft/dbr/delete_builder.go generated vendored Normal file
View File

@@ -0,0 +1,87 @@
package dbr
import (
"context"
"database/sql"
"fmt"
)
type DeleteBuilder struct {
runner
EventReceiver
Dialect Dialect
*DeleteStmt
LimitCount int64
}
func (sess *Session) DeleteFrom(table string) *DeleteBuilder {
return &DeleteBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
DeleteStmt: DeleteFrom(table),
LimitCount: -1,
}
}
func (tx *Tx) DeleteFrom(table string) *DeleteBuilder {
return &DeleteBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
DeleteStmt: DeleteFrom(table),
LimitCount: -1,
}
}
func (sess *Session) DeleteBySql(query string, value ...interface{}) *DeleteBuilder {
return &DeleteBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
DeleteStmt: DeleteBySql(query, value...),
LimitCount: -1,
}
}
func (tx *Tx) DeleteBySql(query string, value ...interface{}) *DeleteBuilder {
return &DeleteBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
DeleteStmt: DeleteBySql(query, value...),
LimitCount: -1,
}
}
func (b *DeleteBuilder) Exec() (sql.Result, error) {
return b.ExecContext(context.Background())
}
func (b *DeleteBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
return exec(ctx, b.runner, b.EventReceiver, b, b.Dialect)
}
func (b *DeleteBuilder) Where(query interface{}, value ...interface{}) *DeleteBuilder {
b.DeleteStmt.Where(query, value...)
return b
}
func (b *DeleteBuilder) Limit(n uint64) *DeleteBuilder {
b.LimitCount = int64(n)
return b
}
func (b *DeleteBuilder) Build(d Dialect, buf Buffer) error {
err := b.DeleteStmt.Build(b.Dialect, buf)
if err != nil {
return err
}
if b.LimitCount >= 0 {
buf.WriteString(" LIMIT ")
buf.WriteString(fmt.Sprint(b.LimitCount))
}
return nil
}

15
vendor/github.com/gocraft/dbr/dialect.go generated vendored Normal file
View File

@@ -0,0 +1,15 @@
package dbr
import "time"
// Dialect abstracts database differences
type Dialect interface {
QuoteIdent(id string) string
EncodeString(s string) string
EncodeBool(b bool) string
EncodeTime(t time.Time) string
EncodeBytes(b []byte) string
Placeholder(n int) string
}

24
vendor/github.com/gocraft/dbr/dialect/dialect.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package dialect
import "strings"
var (
// MySQL dialect
MySQL = mysql{}
// PostgreSQL dialect
PostgreSQL = postgreSQL{}
// SQLite3 dialect
SQLite3 = sqlite3{}
)
const (
timeFormat = "2006-01-02 15:04:05.000000"
)
func quoteIdent(s, quote string) string {
part := strings.SplitN(s, ".", 2)
if len(part) == 2 {
return quoteIdent(part[0], quote) + "." + quoteIdent(part[1], quote)
}
return quote + s + quote
}

66
vendor/github.com/gocraft/dbr/dialect/mysql.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
package dialect
import (
"bytes"
"fmt"
"time"
)
type mysql struct{}
func (d mysql) QuoteIdent(s string) string {
return quoteIdent(s, "`")
}
func (d mysql) EncodeString(s string) string {
buf := new(bytes.Buffer)
buf.WriteRune('\'')
// https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
for i := 0; i < len(s); i++ {
switch s[i] {
case 0:
buf.WriteString(`\0`)
case '\'':
buf.WriteString(`\'`)
case '"':
buf.WriteString(`\"`)
case '\b':
buf.WriteString(`\b`)
case '\n':
buf.WriteString(`\n`)
case '\r':
buf.WriteString(`\r`)
case '\t':
buf.WriteString(`\t`)
case 26:
buf.WriteString(`\Z`)
case '\\':
buf.WriteString(`\\`)
default:
buf.WriteByte(s[i])
}
}
buf.WriteRune('\'')
return buf.String()
}
func (d mysql) EncodeBool(b bool) string {
if b {
return "1"
}
return "0"
}
func (d mysql) EncodeTime(t time.Time) string {
return `'` + t.UTC().Format(timeFormat) + `'`
}
func (d mysql) EncodeBytes(b []byte) string {
return fmt.Sprintf(`0x%x`, b)
}
func (d mysql) Placeholder(_ int) string {
return "?"
}

37
vendor/github.com/gocraft/dbr/dialect/postgresql.go generated vendored Normal file
View File

@@ -0,0 +1,37 @@
package dialect
import (
"fmt"
"strings"
"time"
)
type postgreSQL struct{}
func (d postgreSQL) QuoteIdent(s string) string {
return quoteIdent(s, `"`)
}
func (d postgreSQL) EncodeString(s string) string {
// http://www.postgresql.org/docs/9.2/static/sql-syntax-lexical.html
return `'` + strings.Replace(s, `'`, `''`, -1) + `'`
}
func (d postgreSQL) EncodeBool(b bool) string {
if b {
return "TRUE"
}
return "FALSE"
}
func (d postgreSQL) EncodeTime(t time.Time) string {
return MySQL.EncodeTime(t)
}
func (d postgreSQL) EncodeBytes(b []byte) string {
return fmt.Sprintf(`E'\\x%x'`, b)
}
func (d postgreSQL) Placeholder(n int) string {
return fmt.Sprintf("$%d", n+1)
}

40
vendor/github.com/gocraft/dbr/dialect/sqlite3.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
package dialect
import (
"fmt"
"strings"
"time"
)
type sqlite3 struct{}
func (d sqlite3) QuoteIdent(s string) string {
return quoteIdent(s, `"`)
}
func (d sqlite3) EncodeString(s string) string {
// https://www.sqlite.org/faq.html
return `'` + strings.Replace(s, `'`, `''`, -1) + `'`
}
func (d sqlite3) EncodeBool(b bool) string {
// https://www.sqlite.org/lang_expr.html
if b {
return "1"
}
return "0"
}
func (d sqlite3) EncodeTime(t time.Time) string {
// https://www.sqlite.org/lang_datefunc.html
return MySQL.EncodeTime(t)
}
func (d sqlite3) EncodeBytes(b []byte) string {
// https://www.sqlite.org/lang_expr.html
return fmt.Sprintf(`X'%x'`, b)
}
func (d sqlite3) Placeholder(_ int) string {
return "?"
}

16
vendor/github.com/gocraft/dbr/errors.go generated vendored Normal file
View File

@@ -0,0 +1,16 @@
package dbr
import "errors"
// package errors
var (
ErrNotFound = errors.New("dbr: not found")
ErrNotSupported = errors.New("dbr: not supported")
ErrTableNotSpecified = errors.New("dbr: table not specified")
ErrColumnNotSpecified = errors.New("dbr: column not specified")
ErrInvalidPointer = errors.New("dbr: attempt to load into an invalid pointer")
ErrPlaceholderCount = errors.New("dbr: wrong placeholder count")
ErrInvalidSliceLength = errors.New("dbr: length of slice is 0. length must be >= 1")
ErrCantConvertToTime = errors.New("dbr: can't convert to time.Time")
ErrInvalidTimestring = errors.New("dbr: invalid time string")
)

40
vendor/github.com/gocraft/dbr/event.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
package dbr
// EventReceiver gets events from dbr methods for logging purposes
type EventReceiver interface {
Event(eventName string)
EventKv(eventName string, kvs map[string]string)
EventErr(eventName string, err error) error
EventErrKv(eventName string, err error, kvs map[string]string) error
Timing(eventName string, nanoseconds int64)
TimingKv(eventName string, nanoseconds int64, kvs map[string]string)
}
type kvs map[string]string
var nullReceiver = &NullEventReceiver{}
// NullEventReceiver is a sentinel EventReceiver; use it if the caller doesn't supply one
type NullEventReceiver struct{}
// Event receives a simple notification when various events occur
func (n *NullEventReceiver) Event(eventName string) {}
// EventKv receives a notification when various events occur along with
// optional key/value data
func (n *NullEventReceiver) EventKv(eventName string, kvs map[string]string) {}
// EventErr receives a notification of an error if one occurs
func (n *NullEventReceiver) EventErr(eventName string, err error) error { return err }
// EventErrKv receives a notification of an error if one occurs along with
// optional key/value data
func (n *NullEventReceiver) EventErrKv(eventName string, err error, kvs map[string]string) error {
return err
}
// Timing receives the time an event took to happen
func (n *NullEventReceiver) Timing(eventName string, nanoseconds int64) {}
// TimingKv receives the time an event took to happen along with optional key/value data
func (n *NullEventReceiver) TimingKv(eventName string, nanoseconds int64, kvs map[string]string) {}

18
vendor/github.com/gocraft/dbr/expr.go generated vendored Normal file
View File

@@ -0,0 +1,18 @@
package dbr
// XxxBuilders all support raw query
type raw struct {
Query string
Value []interface{}
}
// Expr should be used when sql syntax is not supported
func Expr(query string, value ...interface{}) Builder {
return &raw{Query: query, Value: value}
}
func (raw *raw) Build(_ Dialect, buf Buffer) error {
buf.WriteString(raw.Query)
buf.WriteValue(raw.Value...)
return nil
}

24
vendor/github.com/gocraft/dbr/ident.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package dbr
// identifier is a type of string
type I string
func (i I) Build(d Dialect, buf Buffer) error {
buf.WriteString(d.QuoteIdent(string(i)))
return nil
}
// As creates an alias for expr. e.g. SELECT `a1` AS `a2`
func (i I) As(alias string) Builder {
return as(i, alias)
}
func as(expr interface{}, alias string) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
buf.WriteString(placeholder)
buf.WriteValue(expr)
buf.WriteString(" AS ")
buf.WriteString(d.QuoteIdent(alias))
return nil
})
}

123
vendor/github.com/gocraft/dbr/insert.go generated vendored Normal file
View File

@@ -0,0 +1,123 @@
package dbr
import (
"bytes"
"reflect"
)
// InsertStmt builds `INSERT INTO ...`
type InsertStmt struct {
raw
Table string
Column []string
Value [][]interface{}
ReturnColumn []string
}
// Build builds `INSERT INTO ...` in dialect
func (b *InsertStmt) Build(d Dialect, buf Buffer) error {
if b.raw.Query != "" {
return b.raw.Build(d, buf)
}
if b.Table == "" {
return ErrTableNotSpecified
}
if len(b.Column) == 0 {
return ErrColumnNotSpecified
}
buf.WriteString("INSERT INTO ")
buf.WriteString(d.QuoteIdent(b.Table))
placeholderBuf := new(bytes.Buffer)
placeholderBuf.WriteString("(")
buf.WriteString(" (")
for i, col := range b.Column {
if i > 0 {
buf.WriteString(",")
placeholderBuf.WriteString(",")
}
buf.WriteString(d.QuoteIdent(col))
placeholderBuf.WriteString(placeholder)
}
buf.WriteString(") VALUES ")
placeholderBuf.WriteString(")")
placeholderStr := placeholderBuf.String()
for i, tuple := range b.Value {
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(placeholderStr)
buf.WriteValue(tuple...)
}
if len(b.ReturnColumn) > 0 {
buf.WriteString(" RETURNING ")
for i, col := range b.ReturnColumn {
if i > 0 {
buf.WriteString(",")
}
buf.WriteString(d.QuoteIdent(col))
}
}
return nil
}
// InsertInto creates an InsertStmt
func InsertInto(table string) *InsertStmt {
return &InsertStmt{
Table: table,
}
}
// InsertBySql creates an InsertStmt from raw query
func InsertBySql(query string, value ...interface{}) *InsertStmt {
return &InsertStmt{
raw: raw{
Query: query,
Value: value,
},
}
}
// Columns adds columns
func (b *InsertStmt) Columns(column ...string) *InsertStmt {
b.Column = column
return b
}
// Values adds a tuple for columns
func (b *InsertStmt) Values(value ...interface{}) *InsertStmt {
b.Value = append(b.Value, value)
return b
}
// Record adds a tuple for columns from a struct
func (b *InsertStmt) Record(structValue interface{}) *InsertStmt {
v := reflect.Indirect(reflect.ValueOf(structValue))
if v.Kind() == reflect.Struct {
var value []interface{}
m := structMap(v)
for _, key := range b.Column {
if val, ok := m[key]; ok {
value = append(value, val.Interface())
} else {
value = append(value, nil)
}
}
b.Values(value...)
}
return b
}
func (b *InsertStmt) Returning(column ...string) *InsertStmt {
b.ReturnColumn = column
return b
}

126
vendor/github.com/gocraft/dbr/insert_builder.go generated vendored Normal file
View File

@@ -0,0 +1,126 @@
package dbr
import (
"context"
"database/sql"
"reflect"
)
type InsertBuilder struct {
runner
EventReceiver
Dialect Dialect
RecordID reflect.Value
*InsertStmt
}
func (sess *Session) InsertInto(table string) *InsertBuilder {
return &InsertBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
InsertStmt: InsertInto(table),
}
}
func (tx *Tx) InsertInto(table string) *InsertBuilder {
return &InsertBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
InsertStmt: InsertInto(table),
}
}
func (sess *Session) InsertBySql(query string, value ...interface{}) *InsertBuilder {
return &InsertBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
InsertStmt: InsertBySql(query, value...),
}
}
func (tx *Tx) InsertBySql(query string, value ...interface{}) *InsertBuilder {
return &InsertBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
InsertStmt: InsertBySql(query, value...),
}
}
func (b *InsertBuilder) Pair(column string, value interface{}) *InsertBuilder {
b.Column = append(b.Column, column)
switch len(b.Value) {
case 0:
b.InsertStmt.Values(value)
case 1:
b.Value[0] = append(b.Value[0], value)
default:
panic("pair only allows one record to insert")
}
return b
}
func (b *InsertBuilder) Exec() (sql.Result, error) {
return b.ExecContext(context.Background())
}
func (b *InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
result, err := exec(ctx, b.runner, b.EventReceiver, b, b.Dialect)
if err != nil {
return nil, err
}
if b.RecordID.IsValid() {
if id, err := result.LastInsertId(); err == nil {
b.RecordID.SetInt(id)
}
}
return result, nil
}
func (b *InsertBuilder) LoadContext(ctx context.Context, value interface{}) error {
_, err := query(ctx, b.runner, b.EventReceiver, b, b.Dialect, value)
return err
}
func (b *InsertBuilder) Load(value interface{}) error {
return b.LoadContext(context.Background(), value)
}
func (b *InsertBuilder) Columns(column ...string) *InsertBuilder {
b.InsertStmt.Columns(column...)
return b
}
func (b *InsertBuilder) Returning(column ...string) *InsertBuilder {
b.InsertStmt.Returning(column...)
return b
}
func (b *InsertBuilder) Record(structValue interface{}) *InsertBuilder {
v := reflect.Indirect(reflect.ValueOf(structValue))
if v.Kind() == reflect.Struct && v.CanSet() {
// ID is recommended by golint here
for _, name := range []string{"Id", "ID"} {
field := v.FieldByName(name)
if field.IsValid() && field.Kind() == reflect.Int64 {
b.RecordID = field
break
}
}
}
b.InsertStmt.Record(structValue)
return b
}
func (b *InsertBuilder) Values(value ...interface{}) *InsertBuilder {
b.InsertStmt.Values(value...)
return b
}

157
vendor/github.com/gocraft/dbr/interpolate.go generated vendored Normal file
View File

@@ -0,0 +1,157 @@
package dbr
import (
"database/sql/driver"
"reflect"
"strconv"
"strings"
"time"
)
type interpolator struct {
Buffer
Dialect
IgnoreBinary bool
N int
}
// InterpolateForDialect replaces placeholder in query with corresponding value in dialect
func InterpolateForDialect(query string, value []interface{}, d Dialect) (string, error) {
i := interpolator{
Buffer: NewBuffer(),
Dialect: d,
}
err := i.interpolate(query, value)
if err != nil {
return "", err
}
return i.String(), nil
}
func (i *interpolator) interpolate(query string, value []interface{}) error {
if strings.Count(query, placeholder) != len(value) {
return ErrPlaceholderCount
}
valueIndex := 0
for {
index := strings.Index(query, placeholder)
if index == -1 {
break
}
i.WriteString(query[:index])
if _, ok := value[valueIndex].([]byte); ok && i.IgnoreBinary {
i.WriteString(i.Placeholder(i.N))
i.N++
i.WriteValue(value[valueIndex])
} else {
err := i.encodePlaceholder(value[valueIndex])
if err != nil {
return err
}
}
query = query[index+len(placeholder):]
valueIndex++
}
// placeholder not found; write remaining query
i.WriteString(query)
return nil
}
func (i *interpolator) encodePlaceholder(value interface{}) error {
if builder, ok := value.(Builder); ok {
pbuf := NewBuffer()
err := builder.Build(i.Dialect, pbuf)
if err != nil {
return err
}
paren := true
switch value.(type) {
case *SelectStmt:
case *union:
default:
paren = false
}
if paren {
i.WriteString("(")
}
err = i.interpolate(pbuf.String(), pbuf.Value())
if err != nil {
return err
}
if paren {
i.WriteString(")")
}
return nil
}
if valuer, ok := value.(driver.Valuer); ok {
// get driver.Valuer's data
var err error
value, err = valuer.Value()
if err != nil {
return err
}
}
if value == nil {
i.WriteString("NULL")
return nil
}
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.String:
i.WriteString(i.EncodeString(v.String()))
return nil
case reflect.Bool:
i.WriteString(i.EncodeBool(v.Bool()))
return nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
i.WriteString(strconv.FormatInt(v.Int(), 10))
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
i.WriteString(strconv.FormatUint(v.Uint(), 10))
return nil
case reflect.Float32, reflect.Float64:
i.WriteString(strconv.FormatFloat(v.Float(), 'f', -1, 64))
return nil
case reflect.Struct:
if v.Type() == reflect.TypeOf(time.Time{}) {
i.WriteString(i.EncodeTime(v.Interface().(time.Time)))
return nil
}
case reflect.Slice:
if v.Type().Elem().Kind() == reflect.Uint8 {
// []byte
i.WriteString(i.EncodeBytes(v.Bytes()))
return nil
}
if v.Len() == 0 {
// FIXME: support zero-length slice
return ErrInvalidSliceLength
}
i.WriteString("(")
for n := 0; n < v.Len(); n++ {
if n > 0 {
i.WriteString(",")
}
err := i.encodePlaceholder(v.Index(n).Interface())
if err != nil {
return err
}
}
i.WriteString(")")
return nil
case reflect.Ptr:
if v.IsNil() {
i.WriteString("NULL")
return nil
}
return i.encodePlaceholder(v.Elem().Interface())
}
return ErrNotSupported
}

41
vendor/github.com/gocraft/dbr/join.go generated vendored Normal file
View File

@@ -0,0 +1,41 @@
package dbr
type joinType uint8
const (
inner joinType = iota
left
right
full
)
func join(t joinType, table interface{}, on interface{}) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
buf.WriteString(" ")
switch t {
case left:
buf.WriteString("LEFT ")
case right:
buf.WriteString("RIGHT ")
case full:
buf.WriteString("FULL ")
}
buf.WriteString("JOIN ")
switch table := table.(type) {
case string:
buf.WriteString(d.QuoteIdent(table))
default:
buf.WriteString(placeholder)
buf.WriteValue(table)
}
buf.WriteString(" ON ")
switch on := on.(type) {
case string:
buf.WriteString(on)
case Builder:
buf.WriteString(placeholder)
buf.WriteValue(on)
}
return nil
})
}

119
vendor/github.com/gocraft/dbr/load.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
package dbr
import (
"database/sql"
"reflect"
)
// Load loads any value from sql.Rows
func Load(rows *sql.Rows, value interface{}) (int, error) {
defer rows.Close()
column, err := rows.Columns()
if err != nil {
return 0, err
}
v := reflect.ValueOf(value)
if v.Kind() != reflect.Ptr || v.IsNil() {
return 0, ErrInvalidPointer
}
v = v.Elem()
isScanner := v.Addr().Type().Implements(typeScanner)
isSlice := v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 && !isScanner
isMap := v.Kind() == reflect.Map && !isScanner
isMapOfSlices := isMap && v.Type().Elem().Kind() == reflect.Slice && v.Type().Elem().Elem().Kind() != reflect.Uint8
if isMap {
v.Set(reflect.MakeMap(v.Type()))
}
count := 0
for rows.Next() {
var elem, keyElem reflect.Value
var ptr []interface{}
var err error
if isMapOfSlices {
elem = reflect.New(v.Type().Elem().Elem()).Elem()
} else if isSlice || isMap {
elem = reflect.New(v.Type().Elem()).Elem()
} else {
elem = v
}
if isMap {
ptr, err = findPtr(column[1:], elem)
if err != nil {
return 0, err
}
keyElem = reflect.New(v.Type().Key()).Elem()
keyPtr, err := findPtr(column[0:1], keyElem)
if err != nil {
return 0, err
}
ptr = append(keyPtr, ptr...)
} else {
ptr, err = findPtr(column, elem)
if err != nil {
return 0, err
}
}
err = rows.Scan(ptr...)
if err != nil {
return 0, err
}
count++
if isSlice {
v.Set(reflect.Append(v, elem))
} else if isMapOfSlices {
s := v.MapIndex(keyElem)
if !s.IsValid() {
s = reflect.Zero(v.Type().Elem())
}
v.SetMapIndex(keyElem, reflect.Append(s, elem))
} else if isMap {
v.SetMapIndex(keyElem, elem)
} else {
break
}
}
return count, nil
}
type dummyScanner struct{}
func (dummyScanner) Scan(interface{}) error {
return nil
}
var (
dummyDest sql.Scanner = dummyScanner{}
typeScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
)
func findPtr(column []string, value reflect.Value) ([]interface{}, error) {
if value.Addr().Type().Implements(typeScanner) {
return []interface{}{value.Addr().Interface()}, nil
}
switch value.Kind() {
case reflect.Struct:
var ptr []interface{}
m := structMap(value)
for _, key := range column {
if val, ok := m[key]; ok {
ptr = append(ptr, val.Addr().Interface())
} else {
ptr = append(ptr, dummyDest)
}
}
return ptr, nil
case reflect.Ptr:
if value.IsNil() {
value.Set(reflect.New(value.Type().Elem()))
}
return findPtr(column, value.Elem())
}
return []interface{}{value.Addr().Interface()}, nil
}

19
vendor/github.com/gocraft/dbr/now.go generated vendored Normal file
View File

@@ -0,0 +1,19 @@
package dbr
import (
"database/sql/driver"
"time"
)
// Now is a value that serializes to the current time
var Now = nowSentinel{}
const timeFormat = "2006-01-02 15:04:05.000000"
type nowSentinel struct{}
// Value implements a valuer for compatibility
func (n nowSentinel) Value() (driver.Value, error) {
now := time.Now().UTC().Format(timeFormat)
return now, nil
}

24
vendor/github.com/gocraft/dbr/order.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package dbr
type direction bool
// orderby directions
// most databases by default use asc
const (
asc direction = false
desc = true
)
func order(column string, dir direction) Builder {
return BuildFunc(func(d Dialect, buf Buffer) error {
// FIXME: no quote ident
buf.WriteString(column)
switch dir {
case asc:
buf.WriteString(" ASC")
case desc:
buf.WriteString(" DESC")
}
return nil
})
}

238
vendor/github.com/gocraft/dbr/select.go generated vendored Normal file
View File

@@ -0,0 +1,238 @@
package dbr
import "fmt"
// SelectStmt builds `SELECT ...`
type SelectStmt struct {
raw
IsDistinct bool
Column []interface{}
Table interface{}
JoinTable []Builder
WhereCond []Builder
Group []Builder
HavingCond []Builder
Order []Builder
LimitCount int64
OffsetCount int64
}
// Build builds `SELECT ...` in dialect
func (b *SelectStmt) Build(d Dialect, buf Buffer) error {
if b.raw.Query != "" {
return b.raw.Build(d, buf)
}
if len(b.Column) == 0 {
return ErrColumnNotSpecified
}
buf.WriteString("SELECT ")
if b.IsDistinct {
buf.WriteString("DISTINCT ")
}
for i, col := range b.Column {
if i > 0 {
buf.WriteString(", ")
}
switch col := col.(type) {
case string:
// FIXME: no quote ident
buf.WriteString(col)
default:
buf.WriteString(placeholder)
buf.WriteValue(col)
}
}
if b.Table != nil {
buf.WriteString(" FROM ")
switch table := b.Table.(type) {
case string:
// FIXME: no quote ident
buf.WriteString(table)
default:
buf.WriteString(placeholder)
buf.WriteValue(table)
}
if len(b.JoinTable) > 0 {
for _, join := range b.JoinTable {
err := join.Build(d, buf)
if err != nil {
return err
}
}
}
}
if len(b.WhereCond) > 0 {
buf.WriteString(" WHERE ")
err := And(b.WhereCond...).Build(d, buf)
if err != nil {
return err
}
}
if len(b.Group) > 0 {
buf.WriteString(" GROUP BY ")
for i, group := range b.Group {
if i > 0 {
buf.WriteString(", ")
}
err := group.Build(d, buf)
if err != nil {
return err
}
}
}
if len(b.HavingCond) > 0 {
buf.WriteString(" HAVING ")
err := And(b.HavingCond...).Build(d, buf)
if err != nil {
return err
}
}
if len(b.Order) > 0 {
buf.WriteString(" ORDER BY ")
for i, order := range b.Order {
if i > 0 {
buf.WriteString(", ")
}
err := order.Build(d, buf)
if err != nil {
return err
}
}
}
if b.LimitCount >= 0 {
buf.WriteString(" LIMIT ")
buf.WriteString(fmt.Sprint(b.LimitCount))
}
if b.OffsetCount >= 0 {
buf.WriteString(" OFFSET ")
buf.WriteString(fmt.Sprint(b.OffsetCount))
}
return nil
}
// Select creates a SelectStmt
func Select(column ...interface{}) *SelectStmt {
return &SelectStmt{
Column: column,
LimitCount: -1,
OffsetCount: -1,
}
}
// From specifies table
func (b *SelectStmt) From(table interface{}) *SelectStmt {
b.Table = table
return b
}
// SelectBySql creates a SelectStmt from raw query
func SelectBySql(query string, value ...interface{}) *SelectStmt {
return &SelectStmt{
raw: raw{
Query: query,
Value: value,
},
LimitCount: -1,
OffsetCount: -1,
}
}
// Distinct adds `DISTINCT`
func (b *SelectStmt) Distinct() *SelectStmt {
b.IsDistinct = true
return b
}
// Where adds a where condition
func (b *SelectStmt) Where(query interface{}, value ...interface{}) *SelectStmt {
switch query := query.(type) {
case string:
b.WhereCond = append(b.WhereCond, Expr(query, value...))
case Builder:
b.WhereCond = append(b.WhereCond, query)
}
return b
}
// Having adds a having condition
func (b *SelectStmt) Having(query interface{}, value ...interface{}) *SelectStmt {
switch query := query.(type) {
case string:
b.HavingCond = append(b.HavingCond, Expr(query, value...))
case Builder:
b.HavingCond = append(b.HavingCond, query)
}
return b
}
// GroupBy specifies columns for grouping
func (b *SelectStmt) GroupBy(col ...string) *SelectStmt {
for _, group := range col {
b.Group = append(b.Group, Expr(group))
}
return b
}
// OrderBy specifies columns for ordering
func (b *SelectStmt) OrderAsc(col string) *SelectStmt {
b.Order = append(b.Order, order(col, asc))
return b
}
func (b *SelectStmt) OrderDesc(col string) *SelectStmt {
b.Order = append(b.Order, order(col, desc))
return b
}
// Limit adds limit
func (b *SelectStmt) Limit(n uint64) *SelectStmt {
b.LimitCount = int64(n)
return b
}
// Offset adds offset
func (b *SelectStmt) Offset(n uint64) *SelectStmt {
b.OffsetCount = int64(n)
return b
}
// Join joins table on condition
func (b *SelectStmt) Join(table, on interface{}) *SelectStmt {
b.JoinTable = append(b.JoinTable, join(inner, table, on))
return b
}
func (b *SelectStmt) LeftJoin(table, on interface{}) *SelectStmt {
b.JoinTable = append(b.JoinTable, join(left, table, on))
return b
}
func (b *SelectStmt) RightJoin(table, on interface{}) *SelectStmt {
b.JoinTable = append(b.JoinTable, join(right, table, on))
return b
}
func (b *SelectStmt) FullJoin(table, on interface{}) *SelectStmt {
b.JoinTable = append(b.JoinTable, join(full, table, on))
return b
}
// As creates alias for select statement
func (b *SelectStmt) As(alias string) Builder {
return as(b, alias)
}

173
vendor/github.com/gocraft/dbr/select_builder.go generated vendored Normal file
View File

@@ -0,0 +1,173 @@
package dbr
import "context"
type SelectBuilder struct {
runner
EventReceiver
Dialect Dialect
*SelectStmt
}
func prepareSelect(a []string) []interface{} {
b := make([]interface{}, len(a))
for i := range a {
b[i] = a[i]
}
return b
}
func (sess *Session) Select(column ...string) *SelectBuilder {
return &SelectBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
SelectStmt: Select(prepareSelect(column)...),
}
}
func (tx *Tx) Select(column ...string) *SelectBuilder {
return &SelectBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
SelectStmt: Select(prepareSelect(column)...),
}
}
func (sess *Session) SelectBySql(query string, value ...interface{}) *SelectBuilder {
return &SelectBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
SelectStmt: SelectBySql(query, value...),
}
}
func (tx *Tx) SelectBySql(query string, value ...interface{}) *SelectBuilder {
return &SelectBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
SelectStmt: SelectBySql(query, value...),
}
}
// DEPRECATED: use LoadOne instead
func (b *SelectBuilder) LoadStruct(value interface{}) error {
return b.LoadOne(value)
}
// DEPRECATED: use Load instead
func (b *SelectBuilder) LoadStructs(value interface{}) (int, error) {
return b.Load(value)
}
// DEPRECATED: use LoadOne instead
func (b *SelectBuilder) LoadValue(value interface{}) error {
return b.LoadOne(value)
}
// DEPRECATED: use Load instead
func (b *SelectBuilder) LoadValues(value interface{}) (int, error) {
return b.Load(value)
}
func (b *SelectBuilder) LoadOneContext(ctx context.Context, value interface{}) error {
count, err := query(ctx, b.runner, b.EventReceiver, b, b.Dialect, value)
if err != nil {
return err
}
if count == 0 {
return ErrNotFound
}
return nil
}
func (b *SelectBuilder) LoadOne(value interface{}) error {
return b.LoadOneContext(context.Background(), value)
}
func (b *SelectBuilder) LoadContext(ctx context.Context, value interface{}) (int, error) {
return query(ctx, b.runner, b.EventReceiver, b, b.Dialect, value)
}
func (b *SelectBuilder) Load(value interface{}) (int, error) {
return b.LoadContext(context.Background(), value)
}
func (b *SelectBuilder) Join(table, on interface{}) *SelectBuilder {
b.SelectStmt.Join(table, on)
return b
}
func (b *SelectBuilder) LeftJoin(table, on interface{}) *SelectBuilder {
b.SelectStmt.LeftJoin(table, on)
return b
}
func (b *SelectBuilder) RightJoin(table, on interface{}) *SelectBuilder {
b.SelectStmt.RightJoin(table, on)
return b
}
func (b *SelectBuilder) FullJoin(table, on interface{}) *SelectBuilder {
b.SelectStmt.FullJoin(table, on)
return b
}
func (b *SelectBuilder) Distinct() *SelectBuilder {
b.SelectStmt.Distinct()
return b
}
func (b *SelectBuilder) From(table interface{}) *SelectBuilder {
b.SelectStmt.From(table)
return b
}
func (b *SelectBuilder) GroupBy(col ...string) *SelectBuilder {
b.SelectStmt.GroupBy(col...)
return b
}
func (b *SelectBuilder) Having(query interface{}, value ...interface{}) *SelectBuilder {
b.SelectStmt.Having(query, value...)
return b
}
func (b *SelectBuilder) Limit(n uint64) *SelectBuilder {
b.SelectStmt.Limit(n)
return b
}
func (b *SelectBuilder) Offset(n uint64) *SelectBuilder {
b.SelectStmt.Offset(n)
return b
}
func (b *SelectBuilder) OrderDir(col string, isAsc bool) *SelectBuilder {
if isAsc {
b.SelectStmt.OrderAsc(col)
} else {
b.SelectStmt.OrderDesc(col)
}
return b
}
func (b *SelectBuilder) Paginate(page, perPage uint64) *SelectBuilder {
b.Limit(perPage)
b.Offset((page - 1) * perPage)
return b
}
func (b *SelectBuilder) OrderBy(col string) *SelectBuilder {
b.SelectStmt.Order = append(b.SelectStmt.Order, Expr(col))
return b
}
func (b *SelectBuilder) Where(query interface{}, value ...interface{}) *SelectBuilder {
b.SelectStmt.Where(query, value...)
return b
}

66
vendor/github.com/gocraft/dbr/select_return.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
package dbr
//
// These are a set of helpers that just call LoadValue and return the value.
// They return (_, ErrNotFound) if nothing was found.
//
// The inclusion of these helpers in the package is not an obvious choice:
// Benefits:
// - slight increase in code clarity/conciseness b/c you can use ":=" to define the variable
//
// count, err := d.Select("COUNT(*)").From("users").Where("x = ?", x).ReturnInt64()
//
// vs
//
// var count int64
// err := d.Select("COUNT(*)").From("users").Where("x = ?", x).LoadValue(&count)
//
// Downsides:
// - very small increase in code cost, although it's not complex code
// - increase in conceptual model / API footprint when presenting the package to new users
// - no functionality that you can't achieve calling .LoadValue directly.
// - There's a lot of possible types. Do we want to include ALL of them? u?int{8,16,32,64}?, strings, null varieties, etc.
// - Let's just do the common, non-null varieties.
// ReturnInt64 executes the SelectStmt and returns the value as an int64
func (b *SelectBuilder) ReturnInt64() (int64, error) {
var v int64
err := b.LoadValue(&v)
return v, err
}
// ReturnInt64s executes the SelectStmt and returns the value as a slice of int64s
func (b *SelectBuilder) ReturnInt64s() ([]int64, error) {
var v []int64
_, err := b.LoadValues(&v)
return v, err
}
// ReturnUint64 executes the SelectStmt and returns the value as an uint64
func (b *SelectBuilder) ReturnUint64() (uint64, error) {
var v uint64
err := b.LoadValue(&v)
return v, err
}
// ReturnUint64s executes the SelectStmt and returns the value as a slice of uint64s
func (b *SelectBuilder) ReturnUint64s() ([]uint64, error) {
var v []uint64
_, err := b.LoadValues(&v)
return v, err
}
// ReturnString executes the SelectStmt and returns the value as a string
func (b *SelectBuilder) ReturnString() (string, error) {
var v string
err := b.LoadValue(&v)
return v, err
}
// ReturnStrings executes the SelectStmt and returns the value as a slice of strings
func (b *SelectBuilder) ReturnStrings() ([]string, error) {
var v []string
_, err := b.LoadValues(&v)
return v, err
}

99
vendor/github.com/gocraft/dbr/transaction.go generated vendored Normal file
View File

@@ -0,0 +1,99 @@
package dbr
import (
"context"
"database/sql"
"time"
)
// Tx is a transaction for the given Session
type Tx struct {
EventReceiver
Dialect Dialect
*sql.Tx
Timeout time.Duration
// normally we don't call the context cancelFunc.
// however, if we start a tx without explictly tx,
// we will need to call this after the transaction.
Cancel func()
}
func (tx *Tx) GetTimeout() time.Duration {
return tx.Timeout
}
func (sess *Session) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
tx, err := sess.Connection.BeginTx(ctx, opts)
if err != nil {
return nil, sess.EventErr("dbr.begin.error", err)
}
sess.Event("dbr.begin")
stx := &Tx{
EventReceiver: sess,
Dialect: sess.Dialect,
Tx: tx,
Cancel: func() {},
}
deadline, ok := ctx.Deadline()
if ok {
stx.Timeout = deadline.Sub(time.Now())
}
return stx, nil
}
// Begin creates a transaction for the given session
func (sess *Session) Begin() (*Tx, error) {
ctx := context.Background()
var cancel func()
timeout := sess.GetTimeout()
if timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, timeout)
}
stx, err := sess.BeginTx(ctx, nil)
if err != nil {
return nil, err
}
if cancel != nil {
stx.Cancel = cancel
}
return stx, nil
}
// Commit finishes the transaction
func (tx *Tx) Commit() error {
defer tx.Cancel()
err := tx.Tx.Commit()
if err != nil {
return tx.EventErr("dbr.commit.error", err)
}
tx.Event("dbr.commit")
return nil
}
// Rollback cancels the transaction
func (tx *Tx) Rollback() error {
defer tx.Cancel()
err := tx.Tx.Rollback()
if err != nil {
return tx.EventErr("dbr.rollback", err)
}
tx.Event("dbr.rollback")
return nil
}
// RollbackUnlessCommitted rollsback the transaction unless it has already been committed or rolled back.
// Useful to defer tx.RollbackUnlessCommitted() -- so you don't have to handle N failure cases
// Keep in mind the only way to detect an error on the rollback is via the event log.
func (tx *Tx) RollbackUnlessCommitted() {
defer tx.Cancel()
err := tx.Tx.Rollback()
if err == sql.ErrTxDone {
// ok
} else if err != nil {
tx.EventErr("dbr.rollback_unless_committed", err)
} else {
tx.Event("dbr.rollback")
}
}

242
vendor/github.com/gocraft/dbr/types.go generated vendored Normal file
View File

@@ -0,0 +1,242 @@
package dbr
import (
"bytes"
"database/sql"
"database/sql/driver"
"encoding/json"
"time"
)
//
// Your app can use these Null types instead of the defaults. The sole benefit you get is a MarshalJSON method that is not retarded.
//
// NullString is a type that can be null or a string
type NullString struct {
sql.NullString
}
// NullFloat64 is a type that can be null or a float64
type NullFloat64 struct {
sql.NullFloat64
}
// NullInt64 is a type that can be null or an int
type NullInt64 struct {
sql.NullInt64
}
// NullTime is a type that can be null or a time
type NullTime struct {
Time time.Time
Valid bool // Valid is true if Time is not NULL
}
// Value implements the driver Valuer interface.
func (n NullTime) Value() (driver.Value, error) {
if !n.Valid {
return nil, nil
}
return n.Time, nil
}
// NullBool is a type that can be null or a bool
type NullBool struct {
sql.NullBool
}
var nullString = []byte("null")
// MarshalJSON correctly serializes a NullString to JSON
func (n NullString) MarshalJSON() ([]byte, error) {
if n.Valid {
return json.Marshal(n.String)
}
return nullString, nil
}
// MarshalJSON correctly serializes a NullInt64 to JSON
func (n NullInt64) MarshalJSON() ([]byte, error) {
if n.Valid {
return json.Marshal(n.Int64)
}
return nullString, nil
}
// MarshalJSON correctly serializes a NullFloat64 to JSON
func (n NullFloat64) MarshalJSON() ([]byte, error) {
if n.Valid {
return json.Marshal(n.Float64)
}
return nullString, nil
}
// MarshalJSON correctly serializes a NullTime to JSON
func (n NullTime) MarshalJSON() ([]byte, error) {
if n.Valid {
return json.Marshal(n.Time)
}
return nullString, nil
}
// MarshalJSON correctly serializes a NullBool to JSON
func (n NullBool) MarshalJSON() ([]byte, error) {
if n.Valid {
return json.Marshal(n.Bool)
}
return nullString, nil
}
// UnmarshalJSON correctly deserializes a NullString from JSON
func (n *NullString) UnmarshalJSON(b []byte) error {
var s interface{}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
return n.Scan(s)
}
// UnmarshalJSON correctly deserializes a NullInt64 from JSON
func (n *NullInt64) UnmarshalJSON(b []byte) error {
var s json.Number
if err := json.Unmarshal(b, &s); err != nil {
return err
}
if s == "" {
return n.Scan(nil)
}
return n.Scan(s)
}
// UnmarshalJSON correctly deserializes a NullFloat64 from JSON
func (n *NullFloat64) UnmarshalJSON(b []byte) error {
var s interface{}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
return n.Scan(s)
}
// UnmarshalJSON correctly deserializes a NullTime from JSON
func (n *NullTime) UnmarshalJSON(b []byte) error {
// scan for null
if bytes.Equal(b, nullString) {
return n.Scan(nil)
}
// scan for JSON timestamp
var t time.Time
if err := json.Unmarshal(b, &t); err != nil {
return err
}
return n.Scan(t)
}
// UnmarshalJSON correctly deserializes a NullBool from JSON
func (n *NullBool) UnmarshalJSON(b []byte) error {
var s interface{}
if err := json.Unmarshal(b, &s); err != nil {
return err
}
return n.Scan(s)
}
func NewNullInt64(v interface{}) (n NullInt64) {
n.Scan(v)
return
}
func NewNullFloat64(v interface{}) (n NullFloat64) {
n.Scan(v)
return
}
func NewNullString(v interface{}) (n NullString) {
n.Scan(v)
return
}
func NewNullTime(v interface{}) (n NullTime) {
n.Scan(v)
return
}
func NewNullBool(v interface{}) (n NullBool) {
n.Scan(v)
return
}
// The `(*NullTime) Scan(interface{})` and `parseDateTime(string, *time.Location)`
// functions are slightly modified versions of code from the github.com/go-sql-driver/mysql
// package. They work with Postgres and MySQL databases. Potential future
// drivers should ensure these will work for them, or come up with an alternative.
//
// Conforming with its licensing terms the copyright notice and link to the licence
// are available below.
//
// Source: https://github.com/go-sql-driver/mysql/blob/527bcd55aab2e53314f1a150922560174b493034/utils.go#L452-L508
// Copyright notice from original developers:
//
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/
// Scan implements the Scanner interface.
// The value type must be time.Time or string / []byte (formatted time-string),
// otherwise Scan fails.
func (n *NullTime) Scan(value interface{}) error {
var err error
if value == nil {
n.Time, n.Valid = time.Time{}, false
return nil
}
switch v := value.(type) {
case time.Time:
n.Time, n.Valid = v, true
return nil
case []byte:
n.Time, err = parseDateTime(string(v), time.UTC)
n.Valid = (err == nil)
return err
case string:
n.Time, err = parseDateTime(v, time.UTC)
n.Valid = (err == nil)
return err
}
n.Valid = false
return nil
}
func parseDateTime(str string, loc *time.Location) (time.Time, error) {
var t time.Time
var err error
base := "0000-00-00 00:00:00.0000000"
switch len(str) {
case 10, 19, 21, 22, 23, 24, 25, 26:
if str == base[:len(str)] {
return t, err
}
t, err = time.Parse(timeFormat[:len(str)], str)
default:
err = ErrInvalidTimestring
return t, err
}
// Adjust location
if err == nil && loc != time.UTC {
y, mo, d := t.Date()
h, mi, s := t.Clock()
t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
}
return t, err
}

43
vendor/github.com/gocraft/dbr/union.go generated vendored Normal file
View File

@@ -0,0 +1,43 @@
package dbr
type union struct {
builder []Builder
all bool
}
func Union(builder ...Builder) interface {
Builder
As(string) Builder
} {
return &union{
builder: builder,
}
}
func UnionAll(builder ...Builder) interface {
Builder
As(string) Builder
} {
return &union{
builder: builder,
all: true,
}
}
func (u *union) Build(d Dialect, buf Buffer) error {
for i, b := range u.builder {
if i > 0 {
buf.WriteString(" UNION ")
if u.all {
buf.WriteString("ALL ")
}
}
buf.WriteString(placeholder)
buf.WriteValue(b)
}
return nil
}
func (u *union) As(alias string) Builder {
return as(u, alias)
}

96
vendor/github.com/gocraft/dbr/update.go generated vendored Normal file
View File

@@ -0,0 +1,96 @@
package dbr
// UpdateStmt builds `UPDATE ...`
type UpdateStmt struct {
raw
Table string
Value map[string]interface{}
WhereCond []Builder
}
// Build builds `UPDATE ...` in dialect
func (b *UpdateStmt) Build(d Dialect, buf Buffer) error {
if b.raw.Query != "" {
return b.raw.Build(d, buf)
}
if b.Table == "" {
return ErrTableNotSpecified
}
if len(b.Value) == 0 {
return ErrColumnNotSpecified
}
buf.WriteString("UPDATE ")
buf.WriteString(d.QuoteIdent(b.Table))
buf.WriteString(" SET ")
i := 0
for col, v := range b.Value {
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(d.QuoteIdent(col))
buf.WriteString(" = ")
buf.WriteString(placeholder)
buf.WriteValue(v)
i++
}
if len(b.WhereCond) > 0 {
buf.WriteString(" WHERE ")
err := And(b.WhereCond...).Build(d, buf)
if err != nil {
return err
}
}
return nil
}
// Update creates an UpdateStmt
func Update(table string) *UpdateStmt {
return &UpdateStmt{
Table: table,
Value: make(map[string]interface{}),
}
}
// UpdateBySql creates an UpdateStmt with raw query
func UpdateBySql(query string, value ...interface{}) *UpdateStmt {
return &UpdateStmt{
raw: raw{
Query: query,
Value: value,
},
Value: make(map[string]interface{}),
}
}
// Where adds a where condition
func (b *UpdateStmt) Where(query interface{}, value ...interface{}) *UpdateStmt {
switch query := query.(type) {
case string:
b.WhereCond = append(b.WhereCond, Expr(query, value...))
case Builder:
b.WhereCond = append(b.WhereCond, query)
}
return b
}
// Set specifies a key-value pair
func (b *UpdateStmt) Set(column string, value interface{}) *UpdateStmt {
b.Value[column] = value
return b
}
// SetMap specifies a list of key-value pair
func (b *UpdateStmt) SetMap(m map[string]interface{}) *UpdateStmt {
for col, val := range m {
b.Set(col, val)
}
return b
}

97
vendor/github.com/gocraft/dbr/update_builder.go generated vendored Normal file
View File

@@ -0,0 +1,97 @@
package dbr
import (
"context"
"database/sql"
"fmt"
)
type UpdateBuilder struct {
runner
EventReceiver
Dialect Dialect
*UpdateStmt
LimitCount int64
}
func (sess *Session) Update(table string) *UpdateBuilder {
return &UpdateBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
UpdateStmt: Update(table),
LimitCount: -1,
}
}
func (tx *Tx) Update(table string) *UpdateBuilder {
return &UpdateBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
UpdateStmt: Update(table),
LimitCount: -1,
}
}
func (sess *Session) UpdateBySql(query string, value ...interface{}) *UpdateBuilder {
return &UpdateBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
UpdateStmt: UpdateBySql(query, value...),
LimitCount: -1,
}
}
func (tx *Tx) UpdateBySql(query string, value ...interface{}) *UpdateBuilder {
return &UpdateBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
UpdateStmt: UpdateBySql(query, value...),
LimitCount: -1,
}
}
func (b *UpdateBuilder) Exec() (sql.Result, error) {
return b.ExecContext(context.Background())
}
func (b *UpdateBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
return exec(ctx, b.runner, b.EventReceiver, b, b.Dialect)
}
func (b *UpdateBuilder) Set(column string, value interface{}) *UpdateBuilder {
b.UpdateStmt.Set(column, value)
return b
}
func (b *UpdateBuilder) SetMap(m map[string]interface{}) *UpdateBuilder {
b.UpdateStmt.SetMap(m)
return b
}
func (b *UpdateBuilder) Where(query interface{}, value ...interface{}) *UpdateBuilder {
b.UpdateStmt.Where(query, value...)
return b
}
func (b *UpdateBuilder) Limit(n uint64) *UpdateBuilder {
b.LimitCount = int64(n)
return b
}
func (b *UpdateBuilder) Build(d Dialect, buf Buffer) error {
err := b.UpdateStmt.Build(b.Dialect, buf)
if err != nil {
return err
}
if b.LimitCount >= 0 {
buf.WriteString(" LIMIT ")
buf.WriteString(fmt.Sprint(b.LimitCount))
}
return nil
}

71
vendor/github.com/gocraft/dbr/util.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
package dbr
import (
"bytes"
"database/sql/driver"
"reflect"
"unicode"
)
func camelCaseToSnakeCase(name string) string {
buf := new(bytes.Buffer)
runes := []rune(name)
for i := 0; i < len(runes); i++ {
buf.WriteRune(unicode.ToLower(runes[i]))
if i != len(runes)-1 && unicode.IsUpper(runes[i+1]) &&
(unicode.IsLower(runes[i]) || unicode.IsDigit(runes[i]) ||
(i != len(runes)-2 && unicode.IsLower(runes[i+2]))) {
buf.WriteRune('_')
}
}
return buf.String()
}
func structMap(value reflect.Value) map[string]reflect.Value {
m := make(map[string]reflect.Value)
structValue(m, value)
return m
}
var (
typeValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
)
func structValue(m map[string]reflect.Value, value reflect.Value) {
if value.Type().Implements(typeValuer) {
return
}
switch value.Kind() {
case reflect.Ptr:
if value.IsNil() {
return
}
structValue(m, value.Elem())
case reflect.Struct:
t := value.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.PkgPath != "" && !field.Anonymous {
// unexported
continue
}
tag := field.Tag.Get("db")
if tag == "-" {
// ignore
continue
}
if tag == "" {
// no tag, but we can record the field name
tag = camelCaseToSnakeCase(field.Name)
}
fieldValue := value.Field(i)
if _, ok := m[tag]; !ok {
m[tag] = fieldValue
}
structValue(m, fieldValue)
}
}
}

202
vendor/github.com/golang/example/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

27
vendor/github.com/golang/example/stringutil/reverse.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/*
Copyright 2014 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package stringutil contains utility functions for working with strings.
package stringutil
// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}

27
vendor/github.com/google/go-querystring/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2013 Google. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

320
vendor/github.com/google/go-querystring/query/encode.go generated vendored Normal file
View File

@@ -0,0 +1,320 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package query implements encoding of structs into URL query parameters.
//
// As a simple example:
//
// type Options struct {
// Query string `url:"q"`
// ShowAll bool `url:"all"`
// Page int `url:"page"`
// }
//
// opt := Options{ "foo", true, 2 }
// v, _ := query.Values(opt)
// fmt.Print(v.Encode()) // will output: "q=foo&all=true&page=2"
//
// The exact mapping between Go values and url.Values is described in the
// documentation for the Values() function.
package query
import (
"bytes"
"fmt"
"net/url"
"reflect"
"strconv"
"strings"
"time"
)
var timeType = reflect.TypeOf(time.Time{})
var encoderType = reflect.TypeOf(new(Encoder)).Elem()
// Encoder is an interface implemented by any type that wishes to encode
// itself into URL values in a non-standard way.
type Encoder interface {
EncodeValues(key string, v *url.Values) error
}
// Values returns the url.Values encoding of v.
//
// Values expects to be passed a struct, and traverses it recursively using the
// following encoding rules.
//
// Each exported struct field is encoded as a URL parameter unless
//
// - the field's tag is "-", or
// - the field is empty and its tag specifies the "omitempty" option
//
// The empty values are false, 0, any nil pointer or interface value, any array
// slice, map, or string of length zero, and any time.Time that returns true
// for IsZero().
//
// The URL parameter name defaults to the struct field name but can be
// specified in the struct field's tag value. The "url" key in the struct
// field's tag value is the key name, followed by an optional comma and
// options. For example:
//
// // Field is ignored by this package.
// Field int `url:"-"`
//
// // Field appears as URL parameter "myName".
// Field int `url:"myName"`
//
// // Field appears as URL parameter "myName" and the field is omitted if
// // its value is empty
// Field int `url:"myName,omitempty"`
//
// // Field appears as URL parameter "Field" (the default), but the field
// // is skipped if empty. Note the leading comma.
// Field int `url:",omitempty"`
//
// For encoding individual field values, the following type-dependent rules
// apply:
//
// Boolean values default to encoding as the strings "true" or "false".
// Including the "int" option signals that the field should be encoded as the
// strings "1" or "0".
//
// time.Time values default to encoding as RFC3339 timestamps. Including the
// "unix" option signals that the field should be encoded as a Unix time (see
// time.Unix())
//
// Slice and Array values default to encoding as multiple URL values of the
// same name. Including the "comma" option signals that the field should be
// encoded as a single comma-delimited value. Including the "space" option
// similarly encodes the value as a single space-delimited string. Including
// the "semicolon" option will encode the value as a semicolon-delimited string.
// Including the "brackets" option signals that the multiple URL values should
// have "[]" appended to the value name. "numbered" will append a number to
// the end of each incidence of the value name, example:
// name0=value0&name1=value1, etc.
//
// Anonymous struct fields are usually encoded as if their inner exported
// fields were fields in the outer struct, subject to the standard Go
// visibility rules. An anonymous struct field with a name given in its URL
// tag is treated as having that name, rather than being anonymous.
//
// Non-nil pointer values are encoded as the value pointed to.
//
// Nested structs are encoded including parent fields in value names for
// scoping. e.g:
//
// "user[name]=acme&user[addr][postcode]=1234&user[addr][city]=SFO"
//
// All other values are encoded using their default string representation.
//
// Multiple fields that encode to the same URL parameter name will be included
// as multiple URL values of the same name.
func Values(v interface{}) (url.Values, error) {
values := make(url.Values)
val := reflect.ValueOf(v)
for val.Kind() == reflect.Ptr {
if val.IsNil() {
return values, nil
}
val = val.Elem()
}
if v == nil {
return values, nil
}
if val.Kind() != reflect.Struct {
return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind())
}
err := reflectValue(values, val, "")
return values, err
}
// reflectValue populates the values parameter from the struct fields in val.
// Embedded structs are followed recursively (using the rules defined in the
// Values function documentation) breadth-first.
func reflectValue(values url.Values, val reflect.Value, scope string) error {
var embedded []reflect.Value
typ := val.Type()
for i := 0; i < typ.NumField(); i++ {
sf := typ.Field(i)
if sf.PkgPath != "" && !sf.Anonymous { // unexported
continue
}
sv := val.Field(i)
tag := sf.Tag.Get("url")
if tag == "-" {
continue
}
name, opts := parseTag(tag)
if name == "" {
if sf.Anonymous && sv.Kind() == reflect.Struct {
// save embedded struct for later processing
embedded = append(embedded, sv)
continue
}
name = sf.Name
}
if scope != "" {
name = scope + "[" + name + "]"
}
if opts.Contains("omitempty") && isEmptyValue(sv) {
continue
}
if sv.Type().Implements(encoderType) {
if !reflect.Indirect(sv).IsValid() {
sv = reflect.New(sv.Type().Elem())
}
m := sv.Interface().(Encoder)
if err := m.EncodeValues(name, &values); err != nil {
return err
}
continue
}
if sv.Kind() == reflect.Slice || sv.Kind() == reflect.Array {
var del byte
if opts.Contains("comma") {
del = ','
} else if opts.Contains("space") {
del = ' '
} else if opts.Contains("semicolon") {
del = ';'
} else if opts.Contains("brackets") {
name = name + "[]"
}
if del != 0 {
s := new(bytes.Buffer)
first := true
for i := 0; i < sv.Len(); i++ {
if first {
first = false
} else {
s.WriteByte(del)
}
s.WriteString(valueString(sv.Index(i), opts))
}
values.Add(name, s.String())
} else {
for i := 0; i < sv.Len(); i++ {
k := name
if opts.Contains("numbered") {
k = fmt.Sprintf("%s%d", name, i)
}
values.Add(k, valueString(sv.Index(i), opts))
}
}
continue
}
for sv.Kind() == reflect.Ptr {
if sv.IsNil() {
break
}
sv = sv.Elem()
}
if sv.Type() == timeType {
values.Add(name, valueString(sv, opts))
continue
}
if sv.Kind() == reflect.Struct {
reflectValue(values, sv, name)
continue
}
values.Add(name, valueString(sv, opts))
}
for _, f := range embedded {
if err := reflectValue(values, f, scope); err != nil {
return err
}
}
return nil
}
// valueString returns the string representation of a value.
func valueString(v reflect.Value, opts tagOptions) string {
for v.Kind() == reflect.Ptr {
if v.IsNil() {
return ""
}
v = v.Elem()
}
if v.Kind() == reflect.Bool && opts.Contains("int") {
if v.Bool() {
return "1"
}
return "0"
}
if v.Type() == timeType {
t := v.Interface().(time.Time)
if opts.Contains("unix") {
return strconv.FormatInt(t.Unix(), 10)
}
return t.Format(time.RFC3339)
}
return fmt.Sprint(v.Interface())
}
// isEmptyValue checks if a value should be considered empty for the purposes
// of omitting fields with the "omitempty" option.
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
if v.Type() == timeType {
return v.Interface().(time.Time).IsZero()
}
return false
}
// tagOptions is the string following a comma in a struct field's "url" tag, or
// the empty string. It does not include the leading comma.
type tagOptions []string
// parseTag splits a struct field's url tag into its name and comma-separated
// options.
func parseTag(tag string) (string, tagOptions) {
s := strings.Split(tag, ",")
return s[0], s[1:]
}
// Contains checks whether the tagOptions contains the specified option.
func (o tagOptions) Contains(option string) bool {
for _, s := range o {
if s == option {
return true
}
}
return false
}

176
vendor/github.com/kubesphere/sonargo/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,124 @@
// Get information on Compute Engine tasks.
package sonargo
import "net/http"
type CeService struct {
client *Client
}
type CeActivityObject struct {
Tasks []*Task `json:"tasks,omitempty"`
}
type CeComponentObject struct {
Current *Task `json:"current,omitempty"`
Queue []*Task `json:"queue,omitempty"`
}
type CeTaskObject struct {
Task *Task `json:"task,omitempty"`
}
type Task struct {
AnalysisID string `json:"analysisId,omitempty"`
ComponentID string `json:"componentId,omitempty"`
ComponentKey string `json:"componentKey,omitempty"`
ComponentName string `json:"componentName,omitempty"`
ComponentQualifier string `json:"componentQualifier,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
ErrorStacktrace string `json:"errorStacktrace,omitempty"`
ErrorType string `json:"errorType,omitempty"`
ExecutedAt string `json:"executedAt,omitempty"`
ExecutionTimeMs int64 `json:"executionTimeMs,omitempty"`
FinishedAt string `json:"finishedAt,omitempty"`
HasErrorStacktrace bool `json:"hasErrorStacktrace,omitempty"`
HasScannerContext bool `json:"hasScannerContext,omitempty"`
ID string `json:"id,omitempty"`
Logs bool `json:"logs,omitempty"`
Organization string `json:"organization,omitempty"`
ScannerContext string `json:"scannerContext,omitempty"`
StartedAt string `json:"startedAt,omitempty"`
Status string `json:"status,omitempty"`
SubmittedAt string `json:"submittedAt,omitempty"`
SubmitterLogin string `json:"submitterLogin,omitempty"`
TaskType string `json:"taskType,omitempty"`
Type string `json:"type,omitempty"`
WarningCount int `json:"warningCount,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
type CeActivityOption struct {
ComponentId string `url:"componentId,omitempty"` // Description:"Id of the component (project) to filter on",ExampleValue:"AU-TpxcA-iU5OvuD2FL0"
MaxExecutedAt string `url:"maxExecutedAt,omitempty"` // Description:"Maximum date of end of task processing (inclusive)",ExampleValue:"2017-10-19T13:00:00+0200"
MinSubmittedAt string `url:"minSubmittedAt,omitempty"` // Description:"Minimum date of task submission (inclusive)",ExampleValue:"2017-10-19T13:00:00+0200"
OnlyCurrents string `url:"onlyCurrents,omitempty"` // Description:"Filter on the last tasks (only the most recent finished task by project)",ExampleValue:""
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 1000",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>component names that contain the supplied string</li><li>component keys that are exactly the same as the supplied string</li><li>task ids that are exactly the same as the supplied string</li></ul>Must not be set together with componentId",ExampleValue:"Apache"
Status string `url:"status,omitempty"` // Description:"Comma separated list of task statuses",ExampleValue:"IN_PROGRESS,SUCCESS"
Type string `url:"type,omitempty"` // Description:"Task type",ExampleValue:"REPORT"
}
// Activity Search for tasks.<br> Requires the system administration permission, or project administration permission if componentId is set.
func (s *CeService) Activity(opt *CeActivityOption) (v *CeActivityObject, resp *http.Response, err error) {
err = s.ValidateActivityOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "ce/activity", opt)
if err != nil {
return
}
v = new(CeActivityObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type CeComponentOption struct {
Component string `url:"component,omitempty"` // Description:"",ExampleValue:"my_project"
ComponentId string `url:"componentId,omitempty"` // Description:"",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Component Get the pending tasks, in-progress tasks and the last executed task of a given component (usually a project).<br>Requires the following permission: 'Browse' on the specified component.<br>Either 'componentId' or 'component' must be provided.
func (s *CeService) Component(opt *CeComponentOption) (v *CeComponentObject, resp *http.Response, err error) {
err = s.ValidateComponentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "ce/component", opt)
if err != nil {
return
}
v = new(CeComponentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type CeTaskOption struct {
AdditionalFields string `url:"additionalFields,omitempty"` // Description:"Comma-separated list of the optional fields to be returned in response.",ExampleValue:""
Id string `url:"id,omitempty"` // Description:"Id of task",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Task Give Compute Engine task details such as type, status, duration and associated component.<br />Requires 'Administer System' or 'Execute Analysis' permission.<br/>Since 6.1, field "logs" is deprecated and its value is always false.
func (s *CeService) Task(opt *CeTaskOption) (v *CeTaskObject, resp *http.Response, err error) {
err = s.ValidateTaskOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "ce/task", opt)
if err != nil {
return
}
v = new(CeTaskObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

123
vendor/github.com/kubesphere/sonargo/sonar/client.go generated vendored Normal file
View File

@@ -0,0 +1,123 @@
package sonargo
import (
"net/http"
"net/url"
)
type Client struct {
baseURL *url.URL
username, password, token string
httpClient *http.Client
Ce *CeService
Components *ComponentsService
Duplications *DuplicationsService
Favorites *FavoritesService
Issues *IssuesService
Languages *LanguagesService
Measures *MeasuresService
Metrics *MetricsService
Notifications *NotificationsService
Permissions *PermissionsService
Plugins *PluginsService
ProjectAnalyses *ProjectAnalysesService
ProjectBadges *ProjectBadgesService
ProjectBranches *ProjectBranchesService
ProjectLinks *ProjectLinksService
ProjectPullRequests *ProjectPullRequestsService
ProjectTags *ProjectTagsService
Projects *ProjectsService
Qualitygates *QualitygatesService
QualityProfiles *QualityProfilesService
Rules *RulesService
Server *ServerService
Settings *SettingsService
Sources *SourcesService
System *SystemService
UserGroups *UserGroupsService
UserTokens *UserTokensService
Users *UsersService
Webhooks *WebhooksService
}
func NewClient(endpoint, username, password string) (*Client, error) {
c := &Client{username: username, password: password, httpClient: http.DefaultClient}
if endpoint == "" {
c.SetBaseURL(defaultBaseURL)
} else {
if err := c.SetBaseURL(endpoint); err != nil {
return nil, err
}
}
c.Ce = &CeService{client: c}
c.Components = &ComponentsService{client: c}
c.Duplications = &DuplicationsService{client: c}
c.Favorites = &FavoritesService{client: c}
c.Issues = &IssuesService{client: c}
c.Languages = &LanguagesService{client: c}
c.Measures = &MeasuresService{client: c}
c.Metrics = &MetricsService{client: c}
c.Notifications = &NotificationsService{client: c}
c.Permissions = &PermissionsService{client: c}
c.Plugins = &PluginsService{client: c}
c.ProjectAnalyses = &ProjectAnalysesService{client: c}
c.ProjectBadges = &ProjectBadgesService{client: c}
c.ProjectBranches = &ProjectBranchesService{client: c}
c.ProjectLinks = &ProjectLinksService{client: c}
c.ProjectPullRequests = &ProjectPullRequestsService{client: c}
c.ProjectTags = &ProjectTagsService{client: c}
c.Projects = &ProjectsService{client: c}
c.Qualitygates = &QualitygatesService{client: c}
c.QualityProfiles = &QualityProfilesService{client: c}
c.Rules = &RulesService{client: c}
c.Server = &ServerService{client: c}
c.Settings = &SettingsService{client: c}
c.Sources = &SourcesService{client: c}
c.System = &SystemService{client: c}
c.UserGroups = &UserGroupsService{client: c}
c.UserTokens = &UserTokensService{client: c}
c.Users = &UsersService{client: c}
c.Webhooks = &WebhooksService{client: c}
return c, nil
}
func NewClientWithToken(endpoint, token string) (*Client, error) {
c := &Client{username: token, password: "", httpClient: http.DefaultClient}
if endpoint == "" {
c.SetBaseURL(defaultBaseURL)
} else {
if err := c.SetBaseURL(endpoint); err != nil {
return nil, err
}
}
c.Ce = &CeService{client: c}
c.Components = &ComponentsService{client: c}
c.Duplications = &DuplicationsService{client: c}
c.Favorites = &FavoritesService{client: c}
c.Issues = &IssuesService{client: c}
c.Languages = &LanguagesService{client: c}
c.Measures = &MeasuresService{client: c}
c.Metrics = &MetricsService{client: c}
c.Notifications = &NotificationsService{client: c}
c.Permissions = &PermissionsService{client: c}
c.Plugins = &PluginsService{client: c}
c.ProjectAnalyses = &ProjectAnalysesService{client: c}
c.ProjectBadges = &ProjectBadgesService{client: c}
c.ProjectBranches = &ProjectBranchesService{client: c}
c.ProjectLinks = &ProjectLinksService{client: c}
c.ProjectPullRequests = &ProjectPullRequestsService{client: c}
c.ProjectTags = &ProjectTagsService{client: c}
c.Projects = &ProjectsService{client: c}
c.Qualitygates = &QualitygatesService{client: c}
c.QualityProfiles = &QualityProfilesService{client: c}
c.Rules = &RulesService{client: c}
c.Server = &ServerService{client: c}
c.Settings = &SettingsService{client: c}
c.Sources = &SourcesService{client: c}
c.System = &SystemService{client: c}
c.UserGroups = &UserGroupsService{client: c}
c.UserTokens = &UserTokensService{client: c}
c.Users = &UsersService{client: c}
c.Webhooks = &WebhooksService{client: c}
return c, nil
}

View File

@@ -0,0 +1,179 @@
package sonargo
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"sort"
"strings"
"github.com/golang/glog"
"github.com/google/go-querystring/query"
)
// SetBaseURL sets the base URL for API requests to a custom endpoint. urlStr
// should always be specified with a trailing slash.
func SetBaseURLUtil(urlStr string) (*url.URL, error) {
// Make sure the given URL end with a slash
if !strings.HasSuffix(urlStr, "/") {
urlStr += "/"
}
baseURL, err := url.Parse(urlStr)
if err != nil {
return nil, err
}
// Update the base URL of the client.
return baseURL, nil
}
// NewRequest creates an API request. A relative URL path can be provided in
// urlStr, in which case it is resolved relative to the base URL of the Client.
// Relative URL paths should always be specified without a preceding slash. If
// specified, the value pointed to by body is JSON encoded and included as the
// request body.
func NewRequest(method, path string, baseURL *url.URL, username, password string, opt interface{}) (*http.Request, error) {
// Set the encoded opaque data
u := *baseURL
unescaped, err := url.PathUnescape(path)
if err != nil {
return nil, err
}
u.RawPath = u.Path + path
u.Path = u.Path + unescaped
if opt != nil {
q, err := query.Values(opt)
if err != nil {
return nil, err
}
u.RawQuery = q.Encode()
}
req := &http.Request{
Method: method,
URL: &u,
Proto: "HTTP/1.1",
Header: make(http.Header),
Host: u.Host,
}
if method == "POST" || method == "PUT" {
//SonarQube use RawQuery even method is POST
bodyBytes, err := json.Marshal(opt)
if err != nil {
return nil, err
}
bodyReader := bytes.NewReader(bodyBytes)
u.RawQuery = ""
req.Body = ioutil.NopCloser(bodyReader)
req.ContentLength = int64(bodyReader.Len())
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("Accept", "application/json")
req.SetBasicAuth(username, password)
return req, nil
}
// Do sends an API request and returns the API response. The API response is
// JSON decoded and stored in the value pointed to by v, or returned as an
// error if an API error has occurred. If v implements the io.Writer
// interface, the raw response body will be written to v, without attempting to
// first decode it.
func Do(c *http.Client, req *http.Request, v interface{}) (*http.Response, error) {
isText := false
if _, ok := v.(*string); ok {
req.Header.Set("Accept", "text/plain")
isText = true
}
glog.V(1).Infof("[%s] %s\n", req.Method, req.URL.String())
resp, err := c.Do(req)
if err != nil {
return nil, err
}
err = CheckResponse(resp)
if err != nil {
return resp, err
}
if v != nil {
defer resp.Body.Close()
if w, ok := v.(io.Writer); ok {
_, err = io.Copy(w, resp.Body)
} else {
if isText {
byts, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, err
}
w := v.(*string)
*w = string(byts)
} else {
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(v)
}
}
}
return resp, err
}
type ErrorResponse struct {
Body []byte
Response *http.Response
Message string
}
func (e *ErrorResponse) Error() string {
u := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, e.Response.Request.URL.RequestURI())
return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, u, e.Response.StatusCode, e.Message)
}
func CheckResponse(r *http.Response) error {
switch r.StatusCode {
case 200, 201, 202, 204, 304:
return nil
}
errorResponse := &ErrorResponse{Response: r}
data, err := ioutil.ReadAll(r.Body)
if err == nil && data != nil {
errorResponse.Body = data
var raw interface{}
if err := json.Unmarshal(data, &raw); err != nil {
errorResponse.Message = string(data)
} else {
errorResponse.Message = parseError(raw)
}
}
return errorResponse
}
func parseError(raw interface{}) string {
switch raw := raw.(type) {
case string:
return raw
case []interface{}:
var errs []string
for _, v := range raw {
errs = append(errs, parseError(v))
}
return fmt.Sprintf("[%s]", strings.Join(errs, ", "))
case map[string]interface{}:
var errs []string
for k, v := range raw {
errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v)))
}
sort.Strings(errs)
return strings.Join(errs, ", ")
default:
return fmt.Sprintf("failed to parse unexpected error type: %T", raw)
}
}

View File

@@ -0,0 +1,125 @@
// Get information about a component (file, directory, project, ...) and its ancestors or descendants. Update a project or module key.
package sonargo
import "net/http"
type ComponentsService struct {
client *Client
}
type ComponentsSearchObject struct {
Components []*Component `json:"components,omitempty"`
Paging *Paging `json:"paging,omitempty"`
}
type ComponentsShowObject struct {
Ancestors []*Component `json:"ancestors,omitempty"`
Component *Component `json:"component,omitempty"`
}
type Component struct {
AnalysisDate string `json:"analysisDate,omitempty"`
Description string `json:"description,omitempty"`
Enabled bool `json:"enabled,omitempty"`
ID string `json:"id,omitempty"`
Key string `json:"key,omitempty"`
Language string `json:"language,omitempty"`
LastAnalysisDate string `json:"lastAnalysisDate,omitempty"`
LeakPeriodDate string `json:"leakPeriodDate,omitempty"`
LongName string `json:"longName,omitempty"`
Measures []*SonarMeasure `json:"measures,omitempty"`
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Path string `json:"path,omitempty"`
Project string `json:"project,omitempty"`
Qualifier string `json:"qualifier,omitempty"`
Tags []string `json:"tags,omitempty"`
UUID string `json:"uuid,omitempty"`
Version string `json:"version,omitempty"`
Visibility string `json:"visibility,omitempty"`
}
type ComponentsTreeObject struct {
BaseComponent Component `json:"baseComponent,omitempty"`
Components []*Component `json:"components,omitempty"`
Paging Paging `json:"paging,omitempty"`
}
type ComponentsSearchOption struct {
Language string `url:"language,omitempty"` // Description:"Language key. If provided, only components for the given language are returned.",ExampleValue:"py"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>component names that contain the supplied string</li><li>component keys that are exactly the same as the supplied string</li></ul>",ExampleValue:"sonar"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers. Possible values are:<ul><li>BRC - Sub-projects</li><li>DIR - Directories</li><li>FIL - Files</li><li>TRK - Projects</li><li>UTS - Test Files</li></ul>",ExampleValue:""
}
// Search Search for components
func (s *ComponentsService) Search(opt *ComponentsSearchOption) (v *ComponentsSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "components/search", opt)
if err != nil {
return
}
v = new(ComponentsSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ComponentsShowOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
ComponentId string `url:"componentId,omitempty"` // Description:"Component id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Show Returns a component (file, directory, project, view…) and its ancestors. The ancestors are ordered from the parent to the root project. The 'componentId' or 'component' parameter must be provided.<br>Requires the following permission: 'Browse' on the project of the specified component.
func (s *ComponentsService) Show(opt *ComponentsShowOption) (v *ComponentsShowObject, resp *http.Response, err error) {
err = s.ValidateShowOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "components/show", opt)
if err != nil {
return
}
v = new(ComponentsShowObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ComponentsTreeOption struct {
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
Component string `url:"component,omitempty"` // Description:"Base component key. The search is based on this component.",ExampleValue:"my_project"
ComponentId string `url:"componentId,omitempty"` // Description:"Base component id. The search is based on this component.",ExampleValue:"AU-TpxcA-iU5OvuD2FLz"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>component names that contain the supplied string</li><li>component keys that are exactly the same as the supplied string</li></ul>",ExampleValue:"FILE_NAM"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers. Possible values are:<ul><li>BRC - Sub-projects</li><li>DIR - Directories</li><li>FIL - Files</li><li>TRK - Projects</li><li>UTS - Test Files</li></ul>",ExampleValue:""
S string `url:"s,omitempty"` // Description:"Comma-separated list of sort fields",ExampleValue:"name, path"
Strategy string `url:"strategy,omitempty"` // Description:"Strategy to search for base component descendants:<ul><li>children: return the children components of the base component. Grandchildren components are not returned</li><li>all: return all the descendants components of the base component. Grandchildren are returned.</li><li>leaves: return all the descendant components (files, in general) which don't have other children. They are the leaves of the component tree.</li></ul>",ExampleValue:""
}
// Tree Navigate through components based on the chosen strategy. The componentId or the component parameter must be provided.<br>Requires the following permission: 'Browse' on the specified project.<br>When limiting search with the q parameter, directories are not returned.
func (s *ComponentsService) Tree(opt *ComponentsTreeOption) (v *ComponentsTreeObject, resp *http.Response, err error) {
err = s.ValidateTreeOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "components/tree", opt)
if err != nil {
return
}
v = new(ComponentsTreeObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,58 @@
// Get duplication information for a project.
package sonargo
import "net/http"
type DuplicationsService struct {
client *Client
}
type DuplicationsShowObject struct {
Duplications []*Duplication `json:"duplications,omitempty"`
Files *Files `json:"files,omitempty"`
}
type Block struct {
Ref string `json:"_ref,omitempty"`
From int64 `json:"from,omitempty"`
Size int64 `json:"size,omitempty"`
}
type Duplication struct {
Blocks []*Block `json:"blocks,omitempty"`
}
type Files struct {
One *File `json:"1,omitempty"`
Two *File `json:"2,omitempty"`
Three *File `json:"3,omitempty"`
}
type File struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
ProjectName string `json:"projectName,omitempty"`
}
type DuplicationsShowOption struct {
Key string `url:"key,omitempty"` // Description:"File key",ExampleValue:"my_project:/src/foo/Bar.php"
Uuid string `url:"uuid,omitempty"` // Description:"File ID. If provided, 'key' must not be provided.",ExampleValue:"584a89f2-8037-4f7b-b82c-8b45d2d63fb2"
}
// Show Get duplications. Require Browse permission on file's project
func (s *DuplicationsService) Show(opt *DuplicationsShowOption) (v *DuplicationsShowObject, resp *http.Response, err error) {
err = s.ValidateShowOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "duplications/show", opt)
if err != nil {
return
}
v = new(DuplicationsShowObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,85 @@
// Manage user favorites
package sonargo
import "net/http"
type FavoritesService struct {
client *Client
}
type FavoritesSearchObject struct {
Favorites []*Favorite `json:"favorites,omitempty"`
Paging Paging `json:"paging,omitempty"`
}
type Favorite struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Qualifier string `json:"qualifier,omitempty"`
}
type FavoritesAddOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project:/src/foo/Bar.php"
}
// Add Add a component (project, directory, file etc.) as favorite for the authenticated user.<br>Requires authentication and the following permission: 'Browse' on the project of the specified component.
func (s *FavoritesService) Add(opt *FavoritesAddOption) (resp *http.Response, err error) {
err = s.ValidateAddOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "favorites/add", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type FavoritesRemoveOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
}
// Remove Remove a component (project, directory, file etc.) as favorite for the authenticated user.<br>Requires authentication.
func (s *FavoritesService) Remove(opt *FavoritesRemoveOption) (resp *http.Response, err error) {
err = s.ValidateRemoveOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "favorites/remove", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type FavoritesSearchOption struct {
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
}
// Search Search for the authenticated user favorites.<br>Requires authentication.
func (s *FavoritesService) Search(opt *FavoritesSearchOption) (v *FavoritesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "favorites/search", opt)
if err != nil {
return
}
v = new(FavoritesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,450 @@
// Read and update issues.
package sonargo
import "net/http"
type IssuesService struct {
client *Client
}
const (
SeverityINFO = "INFO"
SeverityMINOR = "MINOR"
SeverityMAJOR = "MAJOR"
SeverityCRITICAL = "CRITICAL"
SeverityBLOCKER = "BLOCKER"
IssueTypeBug = "BUG"
IssueTypeCodeSmell = "CODE_SMELL"
IssueTypeVulnerability = "VULNERABILITY"
)
type IssuesAddCommentObject struct {
Components []*Component `json:"components,omitempty"`
Issue *Issue `json:"issue,omitempty"`
Rules []*Rule `json:"rules,omitempty"`
Users []*User `json:"users,omitempty"`
}
type IssuesSearchObject struct {
Components []*Component `json:"components,omitempty"`
EffortTotal int `json:"effortTotal,omitempty"`
DebtTotal int `json:"debtTotal,omitempty"`
Issues []*Issue `json:"issues,omitempty"`
P int `json:"p,omitempty"`
Ps int `json:"ps,omitempty"`
Paging *Paging `json:"paging,omitempty"`
Rules []*Rule `json:"rules,omitempty"`
Total int `json:"total,omitempty"`
Users []*User `json:"users,omitempty"`
Facets []*Facet `json:"facets,omitempty"`
}
type Comment struct {
CreatedAt string `json:"createdAt,omitempty"`
HTMLText string `json:"htmlText,omitempty"`
Key string `json:"key,omitempty"`
Login string `json:"login,omitempty"`
Markdown string `json:"markdown,omitempty"`
Updatable bool `json:"updatable,omitempty"`
}
type Issue struct {
Actions []string `json:"actions,omitempty"`
Assignee string `json:"assignee,omitempty"`
Author string `json:"author,omitempty"`
Comments []*Comment `json:"comments,omitempty"`
Component string `json:"component,omitempty"`
CreationDate string `json:"creationDate,omitempty"`
Debt string `json:"debt,omitempty"`
Effort string `json:"effort,omitempty"`
Flows []interface{} `json:"flows,omitempty"`
Hash string `json:"hash,omitempty"`
Key string `json:"key,omitempty"`
Line int `json:"line,omitempty"`
Message string `json:"message,omitempty"`
Organization string `json:"organization,omitempty"`
Project string `json:"project,omitempty"`
Rule string `json:"rule,omitempty"`
Severity string `json:"severity,omitempty"`
Status string `json:"status,omitempty"`
Tags []string `json:"tags,omitempty"`
TextRange *TextRange `json:"textRange,omitempty"`
Transitions []string `json:"transitions,omitempty"`
Type string `json:"type,omitempty"`
UpdateDate string `json:"updateDate,omitempty"`
FromHotspot bool `json:"fromHotspot,omitempty"`
Resolution string `json:"resolution,omitempty"`
CloseDate string `json:"closeDate,omitempty"`
}
type TextRange struct {
EndLine int `json:"endLine,omitempty"`
EndOffset int `json:"endOffset,omitempty"`
StartLine int `json:"startLine,omitempty"`
StartOffset int `json:"startOffset,omitempty"`
}
type IssuesAuthorsObject struct {
Authors []string `json:"authors,omitempty"`
}
type IssuesBulkChangeObject struct {
Failures int `json:"failures,omitempty"`
Ignored int `json:"ignored,omitempty"`
Success int `json:"success,omitempty"`
Total int `json:"total,omitempty"`
}
type IssuesChangelogObject struct {
Changelog []*Changelog `json:"changelog,omitempty"`
}
type Changelog struct {
Avatar string `json:"avatar,omitempty"`
CreationDate string `json:"creationDate,omitempty"`
Diffs []*Diff `json:"diffs,omitempty"`
User string `json:"user,omitempty"`
UserName string `json:"userName,omitempty"`
}
type Diff struct {
Key string `json:"key,omitempty"`
NewValue string `json:"newValue,omitempty"`
OldValue string `json:"oldValue,omitempty"`
}
type IssuesTagsObject struct {
Tags []string `json:"tags,omitempty"`
}
type IssuesAddCommentOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Text string `url:"text,omitempty"` // Description:"Comment text",ExampleValue:"Won't fix because it doesn't apply to the context"
}
// AddComment Add a comment.<br/>Requires authentication and the following permission: 'Browse' on the project of the specified issue.
func (s *IssuesService) AddComment(opt *IssuesAddCommentOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateAddCommentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/add_comment", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesAssignOption struct {
Assignee string `url:"assignee,omitempty"` // Description:"Login of the assignee. When not set, it will unassign the issue. Use '_me' to assign to current user",ExampleValue:"admin"
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Assign Assign/Unassign an issue. Requires authentication and Browse permission on project
func (s *IssuesService) Assign(opt *IssuesAssignOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateAssignOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/assign", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesAuthorsOption struct {
Ps int `url:"ps,omitempty"` // Description:"The size of the list to return",ExampleValue:"25"
Q string `url:"q,omitempty"` // Description:"A pattern to match SCM accounts against",ExampleValue:"luke"
}
// Authors Search SCM accounts which match a given query
func (s *IssuesService) Authors(opt *IssuesAuthorsOption) (v *IssuesAuthorsObject, resp *http.Response, err error) {
err = s.ValidateAuthorsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "issues/authors", opt)
if err != nil {
return
}
v = new(IssuesAuthorsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesBulkChangeOption struct {
AddTags string `url:"add_tags,omitempty"` // Description:"Add tags",ExampleValue:"security,java8"
Assign string `url:"assign,omitempty"` // Description:"To assign the list of issues to a specific user (login), or un-assign all the issues",ExampleValue:"john.smith"
Comment string `url:"comment,omitempty"` // Description:"To add a comment to a list of issues",ExampleValue:"Here is my comment"
DoTransition string `url:"do_transition,omitempty"` // Description:"Transition",ExampleValue:"reopen"
Issues string `url:"issues,omitempty"` // Description:"Comma-separated list of issue keys",ExampleValue:"AU-Tpxb--iU5OvuD2FLy,AU-TpxcA-iU5OvuD2FLz"
Plan string `url:"plan,omitempty"` // Description:"In 5.5, action plans are dropped. Has no effect. To plan the list of issues to a specific action plan (key), or unlink all the issues from an action plan",ExampleValue:""
RemoveTags string `url:"remove_tags,omitempty"` // Description:"Remove tags",ExampleValue:"security,java8"
SendNotifications string `url:"sendNotifications,omitempty"` // Description:"",ExampleValue:""
SetSeverity string `url:"set_severity,omitempty"` // Description:"To change the severity of the list of issues",ExampleValue:"BLOCKER"
SetType string `url:"set_type,omitempty"` // Description:"To change the type of the list of issues",ExampleValue:"BUG"
}
// BulkChange Bulk change on issues.<br/>Requires authentication.
func (s *IssuesService) BulkChange(opt *IssuesBulkChangeOption) (v *IssuesBulkChangeObject, resp *http.Response, err error) {
err = s.ValidateBulkChangeOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/bulk_change", opt)
if err != nil {
return
}
v = new(IssuesBulkChangeObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesChangelogOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Changelog Display changelog of an issue.<br/>Requires the 'Browse' permission on the project of the specified issue.
func (s *IssuesService) Changelog(opt *IssuesChangelogOption) (v *IssuesChangelogObject, resp *http.Response, err error) {
err = s.ValidateChangelogOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "issues/changelog", opt)
if err != nil {
return
}
v = new(IssuesChangelogObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesDeleteCommentOption struct {
Comment string `url:"comment,omitempty"` // Description:"Comment key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// DeleteComment Delete a comment.<br/>Requires authentication and the following permission: 'Browse' on the project of the specified issue.
func (s *IssuesService) DeleteComment(opt *IssuesDeleteCommentOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateDeleteCommentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/delete_comment", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesDoTransitionOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Transition string `url:"transition,omitempty"` // Description:"Transition",ExampleValue:""
}
// DoTransition Do workflow transition on an issue. Requires authentication and Browse permission on project.<br/>The transitions 'wontfix' and 'falsepositive' require the permission 'Administer Issues'.
func (s *IssuesService) DoTransition(opt *IssuesDoTransitionOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateDoTransitionOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/do_transition", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesEditCommentOption struct {
Comment string `url:"comment,omitempty"` // Description:"Comment key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Text string `url:"text,omitempty"` // Description:"Comment text",ExampleValue:"Won't fix because it doesn't apply to the context"
}
// EditComment Edit a comment.<br/>Requires authentication and the following permission: 'Browse' on the project of the specified issue.
func (s *IssuesService) EditComment(opt *IssuesEditCommentOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateEditCommentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/edit_comment", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesSearchOption struct {
AdditionalFields string `url:"additionalFields,omitempty"` // Description:"Comma-separated list of the optional fields to be returned in response. Action plans are dropped in 5.5, it is not returned in the response.",ExampleValue:""
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
Assigned string `url:"assigned,omitempty"` // Description:"To retrieve assigned or unassigned issues",ExampleValue:""
Assignees string `url:"assignees,omitempty"` // Description:"Comma-separated list of assignee logins. The value '__me__' can be used as a placeholder for user who performs the request",ExampleValue:"admin,usera,__me__"
Authors string `url:"authors,omitempty"` // Description:"Comma-separated list of SCM accounts",ExampleValue:"torvalds@linux-foundation.org"
ComponentKeys string `url:"componentKeys,omitempty"` // Description:"Comma-separated list of component keys. Retrieve issues associated to a specific list of components (and all its descendants). A component can be a portfolio, project, module, directory or file.",ExampleValue:"my_project"
ComponentRootUuids string `url:"componentRootUuids,omitempty"` // Description:"If used, will have the same meaning as componentUuids AND onComponentOnly=false.",ExampleValue:""
ComponentRoots string `url:"componentRoots,omitempty"` // Description:"If used, will have the same meaning as componentKeys AND onComponentOnly=false.",ExampleValue:""
ComponentUuids string `url:"componentUuids,omitempty"` // Description:"To retrieve issues associated to a specific list of components their sub-components (comma-separated list of component IDs). This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. A component can be a project, module, directory or file.",ExampleValue:"584a89f2-8037-4f7b-b82c-8b45d2d63fb2"
Components string `url:"components,omitempty"` // Description:"If used, will have the same meaning as componentKeys AND onComponentOnly=true.",ExampleValue:""
CreatedAfter string `url:"createdAfter,omitempty"` // Description:"To retrieve issues created after the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided. <br>If this parameter is set, createdSince must not be set",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
CreatedAt string `url:"createdAt,omitempty"` // Description:"Datetime to retrieve issues created during a specific analysis",ExampleValue:"2017-10-19T13:00:00+0200"
CreatedBefore string `url:"createdBefore,omitempty"` // Description:"To retrieve issues created before the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
CreatedInLast string `url:"createdInLast,omitempty"` // Description:"To retrieve issues created during a time span before the current time (exclusive). Accepted units are 'y' for year, 'm' for month, 'w' for week and 'd' for day. If this parameter is set, createdAfter must not be set",ExampleValue:"1m2w (1 month 2 weeks)"
Facets string `url:"facets,omitempty"` // Description:"Comma-separated list of the facets to be computed. No facet is computed by default."
Issues string `url:"issues,omitempty"` // Description:"Comma-separated list of issue keys",ExampleValue:"5bccd6e8-f525-43a2-8d76-fcb13dde79ef"
Languages string `url:"languages,omitempty"` // Description:"Comma-separated list of languages. Available since 4.4",ExampleValue:"java,js"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Resolutions string `url:"resolutions,omitempty"` // Description:"Comma-separated list of resolutions",ExampleValue:"FIXED,REMOVED"
Resolved string `url:"resolved,omitempty"` // Description:"To match resolved or unresolved issues",ExampleValue:""
Rules string `url:"rules,omitempty"` // Description:"Comma-separated list of coding rule keys. Format is &lt;repository&gt;:&lt;rule&gt;",ExampleValue:"squid:AvoidCycles"
S string `url:"s,omitempty"` // Description:"Sort field",ExampleValue:""
Severities string `url:"severities,omitempty"` // Description:"Comma-separated list of severities",ExampleValue:"BLOCKER,CRITICAL"
SinceLeakPeriod string `url:"sinceLeakPeriod,omitempty"` // Description:"To retrieve issues created since the leak period.<br>If this parameter is set to a truthy value, createdAfter must not be set and one component id or key must be provided.",ExampleValue:""
Statuses string `url:"statuses,omitempty"` // Description:"Comma-separated list of statuses",ExampleValue:"OPEN,REOPENED"
Tags string `url:"tags,omitempty"` // Description:"Comma-separated list of tags.",ExampleValue:"security,convention"
Types string `url:"types,omitempty"` // Description:"Comma-separated list of types.",ExampleValue:"CODE_SMELL,BUG"
}
// Search Search for issues.<br>At most one of the following parameters can be provided at the same time: componentKeys, componentUuids, components, componentRootUuids, componentRoots.<br>Requires the 'Browse' permission on the specified project(s).
func (s *IssuesService) Search(opt *IssuesSearchOption) (v *IssuesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "issues/search", opt)
if err != nil {
return
}
v = new(IssuesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesSetSeverityOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Severity string `url:"severity,omitempty"` // Description:"New severity",ExampleValue:""
}
// SetSeverity Change severity.<br/>Requires the following permissions:<ul> <li>'Authentication'</li> <li>'Browse' rights on project of the specified issue</li> <li>'Administer Issues' rights on project of the specified issue</li></ul>
func (s *IssuesService) SetSeverity(opt *IssuesSetSeverityOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateSetSeverityOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/set_severity", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesSetTagsOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Tags string `url:"tags,omitempty"` // Description:"Comma-separated list of tags. All tags are removed if parameter is empty or not set.",ExampleValue:"security,cwe,misra-c"
}
// SetTags Set tags on an issue. <br/>Requires authentication and Browse permission on project
func (s *IssuesService) SetTags(opt *IssuesSetTagsOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateSetTagsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/set_tags", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesSetTypeOption struct {
Issue string `url:"issue,omitempty"` // Description:"Issue key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Type string `url:"type,omitempty"` // Description:"New type",ExampleValue:""
}
// SetType Change type of issue, for instance from 'code smell' to 'bug'.<br/>Requires the following permissions:<ul> <li>'Authentication'</li> <li>'Browse' rights on project of the specified issue</li> <li>'Administer Issues' rights on project of the specified issue</li></ul>
func (s *IssuesService) SetType(opt *IssuesSetTypeOption) (v *IssuesAddCommentObject, resp *http.Response, err error) {
err = s.ValidateSetTypeOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "issues/set_type", opt)
if err != nil {
return
}
v = new(IssuesAddCommentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type IssuesTagsOption struct {
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 100",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to tags that contain the supplied string.",ExampleValue:"misra"
}
// Tags List tags matching a given query
func (s *IssuesService) Tags(opt *IssuesTagsOption) (v *IssuesTagsObject, resp *http.Response, err error) {
err = s.ValidateTagsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "issues/tags", opt)
if err != nil {
return
}
v = new(IssuesTagsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,40 @@
// Get the list of programming languages supported in this instance.
package sonargo
import "net/http"
type LanguagesService struct {
client *Client
}
type LanguagesListObject struct {
Languages []*Language `json:"languages,omitempty"`
}
type Language struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
}
type LanguagesListOption struct {
Ps int `url:"ps,omitempty"` // Description:"The size of the list to return, 0 for all languages",ExampleValue:"25"
Q string `url:"q,omitempty"` // Description:"A pattern to match language keys/names against",ExampleValue:"java"
}
// List List supported programming languages
func (s *LanguagesService) List(opt *LanguagesListOption) (v *LanguagesListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "languages/list", opt)
if err != nil {
return
}
v = new(LanguagesListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,138 @@
// Get components or children with specified measures.
package sonargo
import (
"net/http"
)
type MeasuresService struct {
client *Client
}
type MeasuresComponentObject struct {
Component *Component `json:"component,omitempty"`
Metrics []*Metric `json:"metrics,omitempty"`
Periods []*Period `json:"periods,omitempty"`
}
type SonarMeasure struct {
Metric string `json:"metric,omitempty"`
Periods []*Period `json:"periods,omitempty"`
Value string `json:"value,omitempty"`
Histories []*History `json:"history,omitempty"`
BestValue bool `json:"bestValue,omitempty"`
}
type Period struct {
Date string `json:"date,omitempty"`
Index int64 `json:"index,omitempty"`
Mode string `json:"mode,omitempty"`
Parameter string `json:"parameter,omitempty"`
Value string `json:"value,omitempty"`
BestValue bool `json:"bestValue,omitempty"`
}
type MeasuresComponentTreeObject struct {
BaseComponent Component `json:"baseComponent,omitempty"`
Components []*Component `json:"components,omitempty"`
Metrics []*Metric `json:"metrics,omitempty"`
Paging Paging `json:"paging,omitempty"`
Periods []*Period `json:"periods,omitempty"`
}
type MeasuresSearchHistoryObject struct {
Measures []*SonarMeasure `json:"measures,omitempty"`
Paging Paging `json:"paging,omitempty"`
}
type History struct {
Date string `json:"date,omitempty"`
Value string `json:"value,omitempty"`
}
type MeasuresComponentOption struct {
AdditionalFields string `url:"additionalFields,omitempty"` // Description:"Comma-separated list of additional fields that can be returned in the response.",ExampleValue:"periods,metrics"
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
ComponentId string `url:"componentId,omitempty"` // Description:"Component id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
MetricKeys string `url:"metricKeys,omitempty"` // Description:"Comma-separated list of metric keys",ExampleValue:"ncloc,complexity,violations"
}
// Component Return component with specified measures. The componentId or the component parameter must be provided.<br>Requires the following permission: 'Browse' on the project of specified component.
func (s *MeasuresService) Component(opt *MeasuresComponentOption) (v *MeasuresComponentObject, resp *http.Response, err error) {
err = s.ValidateComponentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "measures/component", opt)
if err != nil {
return
}
v = new(MeasuresComponentObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type MeasuresComponentTreeOption struct {
AdditionalFields string `url:"additionalFields,omitempty"` // Description:"Comma-separated list of additional fields that can be returned in the response.",ExampleValue:"periods,metrics"
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
BaseComponentId string `url:"baseComponentId,omitempty"` // Description:"Base component id. The search is based on this component.",ExampleValue:"AU-TpxcA-iU5OvuD2FLz"
Component string `url:"component,omitempty"` // Description:"Component key. The search is based on this component.",ExampleValue:"my_project"
MetricKeys string `url:"metricKeys,omitempty"` // Description:"Comma-separated list of metric keys. Types DISTRIB, DATA are not allowed.",ExampleValue:"ncloc,complexity,violations"
MetricPeriodSort string `url:"metricPeriodSort,omitempty"` // Description:"Sort measures by leak period or not ?. The 's' parameter must contain the 'metricPeriod' value.",ExampleValue:""
MetricSort string `url:"metricSort,omitempty"` // Description:"Metric key to sort by. The 's' parameter must contain the 'metric' or 'metricPeriod' value. It must be part of the 'metricKeys' parameter",ExampleValue:"ncloc"
MetricSortFilter string `url:"metricSortFilter,omitempty"` // Description:"Filter components. Sort must be on a metric. Possible values are: <ul><li>all: return all components</li><li>withMeasuresOnly: filter out components that do not have a measure on the sorted metric</li></ul>",ExampleValue:""
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>component names that contain the supplied string</li><li>component keys that are exactly the same as the supplied string</li></ul>",ExampleValue:"FILE_NAM"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers. Possible values are:<ul><li>BRC - Sub-projects</li><li>DIR - Directories</li><li>FIL - Files</li><li>TRK - Projects</li><li>UTS - Test Files</li></ul>",ExampleValue:""
S string `url:"s,omitempty"` // Description:"Comma-separated list of sort fields",ExampleValue:"name,path"
Strategy string `url:"strategy,omitempty"` // Description:"Strategy to search for base component descendants:<ul><li>children: return the children components of the base component. Grandchildren components are not returned</li><li>all: return all the descendants components of the base component. Grandchildren are returned.</li><li>leaves: return all the descendant components (files, in general) which don't have other children. They are the leaves of the component tree.</li></ul>",ExampleValue:""
}
// ComponentTree Navigate through components based on the chosen strategy with specified measures. The baseComponentId or the component parameter must be provided.<br>Requires the following permission: 'Browse' on the specified project.<br>When limiting search with the q parameter, directories are not returned.
func (s *MeasuresService) ComponentTree(opt *MeasuresComponentTreeOption) (v *MeasuresComponentTreeObject, resp *http.Response, err error) {
err = s.ValidateComponentTreeOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "measures/component_tree", opt)
if err != nil {
return
}
v = new(MeasuresComponentTreeObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type MeasuresSearchHistoryOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
From string `url:"from,omitempty"` // Description:"Filter measures created after the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
Metrics string `url:"metrics,omitempty"` // Description:"Comma-separated list of metric keys",ExampleValue:"ncloc,coverage,new_violations"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 1000",ExampleValue:"20"
To string `url:"to,omitempty"` // Description:"Filter measures created before the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
}
// SearchHistory Search measures history of a component.<br>Measures are ordered chronologically.<br>Pagination applies to the number of measures for each metric.<br>Requires the following permission: 'Browse' on the specified component
func (s *MeasuresService) SearchHistory(opt *MeasuresSearchHistoryOption) (v *MeasuresSearchHistoryObject, resp *http.Response, err error) {
err = s.ValidateSearchHistoryOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "measures/search_history", opt)
if err != nil {
return
}
v = new(MeasuresSearchHistoryObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

219
vendor/github.com/kubesphere/sonargo/sonar/metrics.go generated vendored Normal file
View File

@@ -0,0 +1,219 @@
package sonargo
var metrics = []string{
"complexity",
"cognitive_complexity",
"duplicated_blocks",
"duplicated_files",
"duplicated_lines",
"duplicated_lines_density",
"new_violations",
"new_xxx_violations",
"violations",
"xxx_issues",
"false_positive_issues",
"open_issues",
"confirmed_issues",
"reopened_issues",
"code_smells",
"new_code_smells",
"sqale_rating",
"sqale_index",
"new_technical_debt",
"sqale_debt_ratio",
"new_sqale_debt_ratio",
"alert_status",
"quality_gate_details",
"bugs",
"new_bugs",
"reliability_rating",
"reliability_remediation_effort",
"new_reliability_remediation_effort",
"vulnerabilities",
"new_vulnerabilities",
"security_rating",
"security_remediation_effort",
"new_security_remediation_effort",
"classes",
"comment_lines",
"comment_lines_density",
"directories",
"files",
"lines",
"ncloc",
"ncloc_language_distribution",
"functions",
"projects",
"statements",
"branch_coverage",
"new_branch_coverage",
"branch_coverage_hits_data",
"conditions_by_line",
"covered_conditions_by_line",
"coverage",
"new_coverage",
"new_line_coverage",
"coverage_line_hits_data",
"lines_to_cover",
"new_lines_to_cover",
"skipped_tests",
"uncovered_conditions",
"new_uncovered_conditions",
"uncovered_lines",
"new_uncovered_lines",
"tests",
"test_execution_time",
"test_errors",
"test_failures",
"test_success_density",
}
var metricsDescription = []string{
"It is the Cyclomatic Complexity calculated based on the number of paths through the code. Whenever the control flow of a function splits, the complexity counter gets incremented by one. Each function has a minimum complexity of 1. This calculation varies slightly by language because keywords and functionalities do.",
"How hard it is to understand the code's control flow. See the Cognitive Complexity White Paper for a complete description of the mathematical model applied to compute this measure.",
"Number of duplicated blocks of lines.",
"Number of files involved in duplications.",
"Number of lines involved in duplications.",
"= duplicated_lines / lines * 100",
"Number of issues raised for the first time in the New Code period.",
"Number of issues of the specified severity raised for the first time in the New Code period, where xxx is one of: blocker, critical, major, minor, info.",
"Total count of issues in all states.",
"Total count of issues of the specified severity, where xxx is one of: blocker, critical, major, minor, info.",
"Total count of issues marked False Positive",
"Total count of issues in the Open state.",
"Total count of issues in the Confirmed state.",
"Total count of issues in the Reopened state",
"Total count of Code Smell issues.",
"Total count of Code Smell issues raised for the first time in the New Code period.",
"(Formerly the SQALE rating.)\nRating given to your project related to the value of your Technical Debt Ratio. The default Maintainability Rating grid is:",
"Effort to fix all Code Smells. The measure is stored in minutes in the database. An 8-hour day is assumed when values are shown in days.",
"Effort to fix all Code Smells raised for the first time in the New Code period.",
"Ratio between the cost to develop the software and the cost to fix it. The Technical Debt Ratio formula is:\n\nRemediation cost / Development cost\n\nWhich can be restated as:\n\nRemediation cost / (Cost to develop 1 line of code * Number of lines of code)\n\nThe value of the cost to develop a line of code is 0.06 days.",
"Ratio between the cost to develop the code changed in the New Code period and the cost of the issues linked to it.",
"State of the Quality Gate associated to your Project. Possible values are : ERROR, WARN, OK",
"For all the conditions of your Quality Gate, you know which condition is failing and which is not.",
"Number of bug issues.",
"Number of new bug issues.",
"A = 0 Bugs\n\nB = at least 1 Minor Bug\n\nC = at least 1 Major Bug\n\nD = at least 1 Critical Bug\n\nE = at least 1 Blocker Bug ",
"Effort to fix all bug issues. The measure is stored in minutes in the DB. An 8-hour day is assumed when values are shown in days.",
"Same as Reliability remediation effort but on the code changed in the New Code period.",
"Number of vulnerability issues.",
"Number of new vulnerability issues.",
"A = 0 Vulnerabilities\n\nB = at least 1 Minor Vulnerability\n\nC = at least 1 Major Vulnerability\n\nD = at least 1 Critical Vulnerability\n\nE = at least 1 Blocker Vulnerability ",
"Effort to fix all vulnerability issues. The measure is stored in minutes in the DB. An 8-hour day is assumed when values are shown in days.",
"Same as Security remediation effort but on the code changed in the New Code period.",
"Number of classes (including nested classes, interfaces, enums and annotations).",
"Number of lines containing either comment or commented-out code.",
"Density of comment lines = Comment lines / (Lines of code + Comment lines) * 100",
"Number of directories.",
"Number of files.",
"Number of physical lines (number of carriage returns).",
"Number of physical lines that contain at least one character which is neither a whitespace nor a tabulation nor part of a comment.",
"Non Commenting Lines of Code Distributed By Language",
"Number of functions. Depending on the language, a function is either a function or a method or a paragraph.",
"Number of projects in a Portfolio.",
"Number of statements.",
"On each line of code containing some boolean expressions, the condition coverage simply answers the following question: 'Has each boolean expression been evaluated both to true and false?'. This is the density of possible conditions in flow control structures that have been followed during unit tests execution.",
"Identical to Condition coverage but restricted to new / updated source code.",
"List of covered conditions.",
"Number of conditions by line.",
"Number of covered conditions by line.",
"It is a mix of Line coverage and Condition coverage. Its goal is to provide an even more accurate answer to the following question: How much of the source code has been covered by the unit tests?",
"Identical to Coverage but restricted to new / updated source code.",
"Identical to Line coverage but restricted to new / updated source code.",
"List of covered lines.",
"Number of lines of code which could be covered by unit tests (for example, blank lines or full comments lines are not considered as lines to cover).",
"Identical to Lines to cover but restricted to new / updated source code.",
"Number of skipped unit tests.",
"Number of conditions which are not covered by unit tests.",
"Identical to Uncovered conditions but restricted to new / updated source code.",
"Number of lines of code which are not covered by unit tests.",
"Identical to Uncovered lines but restricted to new / updated source code.",
"Number of unit tests.",
"Time required to execute all the unit tests.",
"Number of unit tests that have failed.",
"Number of unit tests that have failed with an unexpected exception.",
"Test success density = (Unit tests - (Unit test errors + Unit test failures)) / Unit tests * 100",
}
var metricNames = []string{
"Complexity",
"Cognitive Complexity",
"Duplicated blocks",
"Duplicated files",
"Duplicated lines",
"Duplicated lines (%)",
"New issues",
"New xxx issues",
"Issues",
"xxx issues",
"False positive issues",
"Open issues",
"Confirmed issues",
"Reopened issues",
"Code Smells",
"New Code Smells",
"Maintainability Rating",
"Technical Debt",
"Technical Debt on New Code",
"Technical Debt Ratio",
"Technical Debt Ratio on New Code",
"Quality Gate Status",
"Quality Gate Details",
"Bugs",
"New Bugs",
"Reliability Rating",
"Reliability remediation effort",
"Reliability remediation effort on new code",
"Vulnerabilities",
"New Vulnerabilities",
"Security Rating",
"Security remediation effort",
"Security remedation effort on new code",
"Classes",
"Comment lines",
"Comments (%)",
"Directories",
"Files",
"Lines",
"Lines of code",
"Lines of code per language",
"Functions",
"Projects",
"Statements",
"Condition coverage",
"Condition coverage on new code",
"Condition coverage hits",
"Conditions by line",
"Covered conditions by line",
"Coverage",
"Coverage on new code",
"Line coverage on new code",
"Line coverage hits",
"Lines to cover",
"Lines to cover on new code",
"Skipped unit tests",
"Uncovered conditions",
"Uncovered conditions on new code",
"Uncovered lines",
"Uncovered lines on new code",
"Unit tests",
"Unit tests duration",
"Unit test errors",
"Unit test failures",
"Unit test success density (%)",
}
const (
MetricTypeINT = "INT"
MetricTypeFLOAT = "FLOAT"
MetricTypePERCENT = "PERCENT"
MetricTypeBOOL = "BOOL"
MetricTypeSTRING = "STRING"
MetricTypeMILLISEC = "MILLISEC"
MetricTypeDATA = "DATA"
MetricTypeLEVEL = "LEVEL"
MetricTypeDISTRIB = "DISTRIB"
MetricTypeRATING = "RATING"
MetricTypeWORK_DUR = "WORK_DUR"
)

View File

@@ -0,0 +1,164 @@
// Get information on automatic metrics, and manage custom metrics. See also api/custom_measures.
package sonargo
import "net/http"
type MetricsService struct {
client *Client
}
type Metric struct {
ID string `url:"id,omitempty" json:"id,omitempty"`
Description string `url:"description,omitempty"` // Description:"Description",ExampleValue:"Size of the team"
Direction int `json:"direction"`
Domain string `url:"domain,omitempty"` // Description:"Domain",ExampleValue:"Tests"
Key string `url:"key,omitempty"` // Description:"Key",ExampleValue:"team_size"
Name string `url:"name,omitempty"` // Description:"Name",ExampleValue:"Team Size"
Type string `url:"type,omitempty"` // Description:"Metric type key",ExampleValue:"INT"
Qualitative bool `json:"qualitative,omitempty"`
Hidden bool `json:"hidden,omitempty"`
Custom bool `json:"custom,omitempty"`
DecimalScale int `json:"decimalScale,omitempty"`
}
func (s *MetricsService) GetDefaultMetrics() []Metric {
result := []Metric{}
for index, key := range metrics {
result = append(result, Metric{
Key: key,
Name: metricNames[index],
Description: metricsDescription[index],
})
}
return result
}
type MetricsDomainsObject struct {
Domains []string `json:"domains,omitempty"`
}
type MetricsSearchObject struct {
Metrics []*Metric `json:"metrics,omitempty"`
P int64 `json:"p,omitempty"`
Ps int64 `json:"ps,omitempty"`
Total int64 `json:"total,omitempty"`
}
type MetricsTypesObject struct {
Types []string `json:"types,omitempty"`
}
type MetricsCreateOption Metric
// Create Create custom metric.<br /> Requires 'Administer System' permission.
func (s *MetricsService) Create(opt *MetricsCreateOption) (v *Metric, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "metrics/create", opt)
if err != nil {
return
}
v = new(Metric)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type MetricsDeleteOption struct {
Ids string `url:"ids,omitempty"` // Description:"Metrics ids to delete.",ExampleValue:"5, 23, 42"
Keys string `url:"keys,omitempty"` // Description:"Metrics keys to delete",ExampleValue:"team_size, business_value"
}
// Delete Delete metrics and associated measures. Delete only custom metrics.<br />Ids or keys must be provided. <br />Requires 'Administer System' permission.
func (s *MetricsService) Delete(opt *MetricsDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "metrics/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
// Domains List all custom metric domains.
func (s *MetricsService) Domains() (v *MetricsDomainsObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "metrics/domains", nil)
if err != nil {
return
}
v = new(MetricsDomainsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type MetricsSearchOption struct {
F string `url:"f,omitempty"` // Description:"Comma-separated list of the fields to be returned in response. All the fields are returned by default.",ExampleValue:""
IsCustom string `url:"isCustom,omitempty"` // Description:"Choose custom metrics following 3 cases:<ul><li>true: only custom metrics are returned</li><li>false: only non custom metrics are returned</li><li>not specified: all metrics are returned</li></ul>",ExampleValue:"true"
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
}
// Search Search for metrics
func (s *MetricsService) Search(opt *MetricsSearchOption) (v *MetricsSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "metrics/search", opt)
if err != nil {
return
}
v = new(MetricsSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Types List all available metric types.
func (s *MetricsService) Types() (v *MetricsTypesObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "metrics/types", nil)
if err != nil {
return
}
v = new(MetricsTypesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type MetricsUpdateOption Metric
// Update Update a custom metric.<br /> Requires 'Administer System' permission.
func (s *MetricsService) Update(opt *MetricsUpdateOption) (v *Metric, resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "metrics/update", opt)
if err != nil {
return
}
v = new(Metric)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,93 @@
// Manage notifications of the authenticated user
package sonargo
import "net/http"
type NotificationsService struct {
client *Client
}
type NotificationsListObject struct {
Channels []string `json:"channels,omitempty"`
GlobalTypes []string `json:"globalTypes,omitempty"`
Notifications []*Notification `json:"notifications,omitempty"`
PerProjectTypes []string `json:"perProjectTypes,omitempty"`
}
type Notification struct {
Channel string `json:"channel,omitempty"`
Organization string `json:"organization,omitempty"`
Project string `json:"project,omitempty"`
ProjectName string `json:"projectName,omitempty"`
Type string `json:"type,omitempty"`
}
type NotificationsAddOption struct {
Channel string `url:"channel,omitempty"` // Description:"Channel through which the notification is sent. For example, notifications can be sent by email.",ExampleValue:""
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:""
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Type string `url:"type,omitempty"` // Description:"Notification type. Possible values are for:<ul> <li>Global notifications: CeReportTaskFailure, ChangesOnMyIssue, NewAlerts, NewFalsePositiveIssue, NewIssues, SQ-MyNewIssues</li> <li>Per project notifications: CeReportTaskFailure, ChangesOnMyIssue, NewAlerts, NewFalsePositiveIssue, NewIssues, SQ-MyNewIssues</li></ul>",ExampleValue:"SQ-MyNewIssues"
}
// Add Add a notification for the authenticated user.<br>Requires one of the following permissions:<ul> <li>Authentication if no login is provided. If a project is provided, requires the 'Browse' permission on the specified project.</li> <li>System administration if a login is provided. If a project is provided, requires the 'Browse' permission on the specified project.</li></ul>
func (s *NotificationsService) Add(opt *NotificationsAddOption) (resp *http.Response, err error) {
err = s.ValidateAddOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "notifications/add", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type NotificationsListOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:""
}
// List List notifications of the authenticated user.<br>Requires one of the following permissions:<ul> <li>Authentication if no login is provided</li> <li>System administration if a login is provided</li></ul>
func (s *NotificationsService) List(opt *NotificationsListOption) (v *NotificationsListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "notifications/list", opt)
if err != nil {
return
}
v = new(NotificationsListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type NotificationsRemoveOption struct {
Channel string `url:"channel,omitempty"` // Description:"Channel through which the notification is sent. For example, notifications can be sent by email.",ExampleValue:""
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:""
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Type string `url:"type,omitempty"` // Description:"Notification type. Possible values are for:<ul> <li>Global notifications: CeReportTaskFailure, ChangesOnMyIssue, NewAlerts, NewFalsePositiveIssue, NewIssues, SQ-MyNewIssues</li> <li>Per project notifications: CeReportTaskFailure, ChangesOnMyIssue, NewAlerts, NewFalsePositiveIssue, NewIssues, SQ-MyNewIssues</li></ul>",ExampleValue:"SQ-MyNewIssues"
}
// Remove Remove a notification for the authenticated user.<br>Requires one of the following permissions:<ul> <li>Authentication if no login is provided</li> <li>System administration if a login is provided</li></ul>
func (s *NotificationsService) Remove(opt *NotificationsRemoveOption) (resp *http.Response, err error) {
err = s.ValidateRemoveOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "notifications/remove", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,425 @@
// Manage permission templates, and the granting and revoking of permissions at the global and project levels.
package sonargo
import "net/http"
type PermissionsService struct {
client *Client
}
type PermissionsCreateTemplateObject struct {
PermissionTemplate *PermissionTemplate `json:"permissionTemplate,omitempty"`
}
type PermissionTemplate struct {
ID string `json:"id,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
UpdatedAt string `json:"updatedAt,omitempty"`
Description string `json:"description,omitempty"`
Name string `json:"name,omitempty"`
ProjectKeyPattern string `json:"projectKeyPattern,omitempty"`
Permissions []*Permission `json:"permissions,omitempty"`
}
type Permission struct {
Description string `json:"description,omitempty"`
GroupsCount int64 `json:"groupsCount,omitempty"`
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
UsersCount int64 `json:"usersCount,omitempty"`
WithProjectCreator bool `json:"withProjectCreator,omitempty"`
}
type PermissionsSearchTemplatesObject struct {
DefaultTemplates []*DefaultTemplate `json:"defaultTemplates,omitempty"`
PermissionTemplates []*PermissionTemplate `json:"permissionTemplates,omitempty"`
Permissions []*Permission `json:"permissions,omitempty"`
}
type DefaultTemplate struct {
Qualifier string `json:"qualifier,omitempty"`
TemplateID string `json:"templateId,omitempty"`
}
type PermissionsAddGroupOption struct {
GroupId int `url:"groupId,omitempty"` // Description:"Group id",ExampleValue:"42"
GroupName string `url:"groupName,omitempty"` // Description:"Group name or 'anyone' (case insensitive)",ExampleValue:"sonar-administrators"
Permission string `url:"permission,omitempty"` // Description:"Permission<ul><li>Possible values for global permissions: admin, profileadmin, gateadmin, scan, provisioning</li><li>Possible values for project permissions admin, codeviewer, issueadmin, scan, user</li></ul>",ExampleValue:""
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"ce4c03d6-430f-40a9-b777-ad877c00aa4d"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// AddGroup Add permission to a group.<br /> This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.<br /> The group name or group id must be provided. <br />Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *PermissionsService) AddGroup(opt *PermissionsAddGroupOption) (resp *http.Response, err error) {
err = s.ValidateAddGroupOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/add_group", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsAddGroupToTemplateOption struct {
GroupId int `url:"groupId,omitempty"` // Description:"Group id",ExampleValue:"42"
GroupName string `url:"groupName,omitempty"` // Description:"Group name or 'anyone' (case insensitive)",ExampleValue:"sonar-administrators"
Permission string `url:"permission,omitempty"` // Description:"Permission<ul><li>Possible values for project permissions admin, codeviewer, issueadmin, scan, user</li></ul>",ExampleValue:""
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// AddGroupToTemplate Add a group to a permission template.<br /> The group id or group name must be provided. <br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) AddGroupToTemplate(opt *PermissionsAddGroupToTemplateOption) (resp *http.Response, err error) {
err = s.ValidateAddGroupToTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/add_group_to_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsAddProjectCreatorToTemplateOption struct {
Permission string `url:"permission,omitempty"` // Description:"Permission<ul><li>Possible values for project permissions admin, codeviewer, issueadmin, scan, user</li></ul>",ExampleValue:""
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// AddProjectCreatorToTemplate Add a project creator to a permission template.<br>Requires the following permission: 'Administer System'.
func (s *PermissionsService) AddProjectCreatorToTemplate(opt *PermissionsAddProjectCreatorToTemplateOption) (resp *http.Response, err error) {
err = s.ValidateAddProjectCreatorToTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/add_project_creator_to_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsAddUserOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
Permission string `url:"permission,omitempty"` // Description:"Permission<ul><li>Possible values for global permissions: admin, profileadmin, gateadmin, scan, provisioning</li><li>Possible values for project permissions admin, codeviewer, issueadmin, scan, user</li></ul>",ExampleValue:""
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"ce4c03d6-430f-40a9-b777-ad877c00aa4d"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// AddUser Add permission to a user.<br /> This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.<br />Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *PermissionsService) AddUser(opt *PermissionsAddUserOption) (resp *http.Response, err error) {
err = s.ValidateAddUserOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/add_user", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsAddUserToTemplateOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
Permission string `url:"permission,omitempty"` // Description:"Permission<ul><li>Possible values for project permissions admin, codeviewer, issueadmin, scan, user</li></ul>",ExampleValue:""
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// AddUserToTemplate Add a user to a permission template.<br /> Requires the following permission: 'Administer System'.
func (s *PermissionsService) AddUserToTemplate(opt *PermissionsAddUserToTemplateOption) (resp *http.Response, err error) {
err = s.ValidateAddUserToTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/add_user_to_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsApplyTemplateOption struct {
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"ce4c03d6-430f-40a9-b777-ad877c00aa4d"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// ApplyTemplate Apply a permission template to one project.<br>The project id or project key must be provided.<br>The template id or name must be provided.<br>Requires the following permission: 'Administer System'.
func (s *PermissionsService) ApplyTemplate(opt *PermissionsApplyTemplateOption) (resp *http.Response, err error) {
err = s.ValidateApplyTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/apply_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsBulkApplyTemplateOption struct {
AnalyzedBefore string `url:"analyzedBefore,omitempty"` // Description:"Filter the projects for which last analysis is older than the given date (exclusive).<br> Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
OnProvisionedOnly string `url:"onProvisionedOnly,omitempty"` // Description:"Filter the projects that are provisioned",ExampleValue:""
Projects string `url:"projects,omitempty"` // Description:"Comma-separated list of project keys",ExampleValue:"my_project,another_project"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>project names that contain the supplied string</li><li>project keys that are exactly the same as the supplied string</li></ul>",ExampleValue:"apac"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers. Possible values are:<ul><li>TRK - Projects</li></ul>",ExampleValue:""
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// BulkApplyTemplate Apply a permission template to several projects.<br />The template id or name must be provided.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) BulkApplyTemplate(opt *PermissionsBulkApplyTemplateOption) (resp *http.Response, err error) {
err = s.ValidateBulkApplyTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/bulk_apply_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsCreateTemplateOption struct {
Description string `url:"description,omitempty"` // Description:"Description",ExampleValue:"Permissions for all projects related to the financial service"
Name string `url:"name,omitempty"` // Description:"Name",ExampleValue:"Financial Service Permissions"
ProjectKeyPattern string `url:"projectKeyPattern,omitempty"` // Description:"Project key pattern. Must be a valid Java regular expression",ExampleValue:".*\.finance\..*"
}
// CreateTemplate Create a permission template.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) CreateTemplate(opt *PermissionsCreateTemplateOption) (v *PermissionsCreateTemplateObject, resp *http.Response, err error) {
err = s.ValidateCreateTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/create_template", opt)
if err != nil {
return
}
v = new(PermissionsCreateTemplateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type PermissionsDeleteTemplateOption struct {
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// DeleteTemplate Delete a permission template.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) DeleteTemplate(opt *PermissionsDeleteTemplateOption) (resp *http.Response, err error) {
err = s.ValidateDeleteTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/delete_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsRemoveGroupOption PermissionsAddGroupOption
// RemoveGroup Remove a permission from a group.<br /> This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.<br /> The group id or group name must be provided, not both.<br />Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *PermissionsService) RemoveGroup(opt *PermissionsRemoveGroupOption) (resp *http.Response, err error) {
err = s.ValidateRemoveGroupOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/remove_group", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsRemoveGroupFromTemplateOption PermissionsAddGroupToTemplateOption
// RemoveGroupFromTemplate Remove a group from a permission template.<br /> The group id or group name must be provided. <br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) RemoveGroupFromTemplate(opt *PermissionsRemoveGroupFromTemplateOption) (resp *http.Response, err error) {
err = s.ValidateRemoveGroupFromTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/remove_group_from_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsRemoveProjectCreatorFromTemplateOption PermissionsAddProjectCreatorToTemplateOption
// RemoveProjectCreatorFromTemplate Remove a project creator from a permission template.<br>Requires the following permission: 'Administer System'.
func (s *PermissionsService) RemoveProjectCreatorFromTemplate(opt *PermissionsRemoveProjectCreatorFromTemplateOption) (resp *http.Response, err error) {
err = s.ValidateRemoveProjectCreatorFromTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/remove_project_creator_from_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsRemoveUserOption PermissionsAddUserOption
// RemoveUser Remove permission from a user.<br /> This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.<br /> Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *PermissionsService) RemoveUser(opt *PermissionsRemoveUserOption) (resp *http.Response, err error) {
err = s.ValidateRemoveUserOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/remove_user", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsRemoveUserFromTemplateOption PermissionsAddUserToTemplateOption
// RemoveUserFromTemplate Remove a user from a permission template.<br /> Requires the following permission: 'Administer System'.
func (s *PermissionsService) RemoveUserFromTemplate(opt *PermissionsRemoveUserFromTemplateOption) (resp *http.Response, err error) {
err = s.ValidateRemoveUserFromTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/remove_user_from_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsSearchTemplatesOption struct {
Q string `url:"q,omitempty"` // Description:"Limit search to permission template names that contain the supplied string.",ExampleValue:"defau"
}
// SearchTemplates List permission templates.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) SearchTemplates(opt *PermissionsSearchTemplatesOption) (v *PermissionsSearchTemplatesObject, resp *http.Response, err error) {
err = s.ValidateSearchTemplatesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "permissions/search_templates", opt)
if err != nil {
return
}
v = new(PermissionsSearchTemplatesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type PermissionsSetDefaultTemplateOption struct {
Qualifier string `url:"qualifier,omitempty"` // Description:"Project qualifier. Filter the results with the specified qualifier. Possible values are:<ul><li>TRK - Projects</li></ul>",ExampleValue:""
TemplateId string `url:"templateId,omitempty"` // Description:"Template id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
TemplateName string `url:"templateName,omitempty"` // Description:"Template name",ExampleValue:"Default Permission Template for Projects"
}
// SetDefaultTemplate Set a permission template as default.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) SetDefaultTemplate(opt *PermissionsSetDefaultTemplateOption) (resp *http.Response, err error) {
err = s.ValidateSetDefaultTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/set_default_template", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PermissionsUpdateTemplateOption struct {
Description string `url:"description,omitempty"` // Description:"Description",ExampleValue:"Permissions for all projects related to the financial service"
Id string `url:"id,omitempty"` // Description:"Id",ExampleValue:"af8cb8cc-1e78-4c4e-8c00-ee8e814009a5"
Name string `url:"name,omitempty"` // Description:"Name",ExampleValue:"Financial Service Permissions"
ProjectKeyPattern string `url:"projectKeyPattern,omitempty"` // Description:"Project key pattern. Must be a valid Java regular expression",ExampleValue:".*\.finance\..*"
}
// UpdateTemplate Update a permission template.<br />Requires the following permission: 'Administer System'.
func (s *PermissionsService) UpdateTemplate(opt *PermissionsUpdateTemplateOption) (v *PermissionsCreateTemplateObject, resp *http.Response, err error) {
err = s.ValidateUpdateTemplateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "permissions/update_template", opt)
if err != nil {
return
}
v = new(PermissionsCreateTemplateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,207 @@
// Manage the plugins on the server, including installing, uninstalling, and upgrading.
package sonargo
import "net/http"
type PluginsService struct {
client *Client
}
type Plugin struct {
Category string `json:"category,omitempty"`
Description string `json:"description,omitempty"`
EditionBundled bool `json:"editionBundled,omitempty"`
Filename string `json:"filename,omitempty"`
Hash string `json:"hash,omitempty"`
HomepageURL string `json:"homepageUrl,omitempty"`
ImplementationBuild string `json:"implementationBuild,omitempty"`
IssueTrackerURL string `json:"issueTrackerUrl,omitempty"`
Key string `json:"key,omitempty"`
License string `json:"license,omitempty"`
Name string `json:"name,omitempty"`
OrganizationName string `json:"organizationName,omitempty"`
OrganizationURL string `json:"organizationUrl,omitempty"`
Release *Release `json:"release,omitempty"`
SonarLintSupported bool `json:"sonarLintSupported,omitempty"`
TermsAndConditionsURL string `json:"termsAndConditionsUrl,omitempty"`
Update *Update `json:"update,omitempty"`
Updates []*Update `json:"updates,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
Version string `json:"version,omitempty"`
}
type PluginsAvailableObject struct {
Plugins []*Plugin `json:"plugins,omitempty"`
UpdateCenterRefresh string `json:"updateCenterRefresh,omitempty"`
}
type Release struct {
Date string `json:"date,omitempty"`
Version string `json:"version,omitempty"`
Description string `json:"description,omitempty"`
ChangeLogURL string `json:"changeLogUrl,omitempty"`
}
type Require struct {
Description string `json:"description,omitempty"`
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
}
type Update struct {
Release *Release `json:"release,omitempty"`
Requires []*Require `json:"requires,omitempty"`
Status string `json:"status,omitempty"`
}
type PluginsInstalledObject struct {
Plugins []*Plugin `json:"plugins,omitempty"`
}
type PluginsPendingObject struct {
Installing []*Plugin `json:"installing,omitempty"`
Removing []*Plugin `json:"removing,omitempty"`
Updating []*Plugin `json:"updating,omitempty"`
}
type PluginsUpdatesObject PluginsAvailableObject
// Available Get the list of all the plugins available for installation on the SonarQube instance, sorted by plugin name.<br/>Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response.<br/>Update status values are: <ul><li>COMPATIBLE: plugin is compatible with current SonarQube instance.</li><li>INCOMPATIBLE: plugin is not compatible with current SonarQube instance.</li><li>REQUIRES_SYSTEM_UPGRADE: plugin requires SonarQube to be upgraded before being installed.</li><li>DEPS_REQUIRE_SYSTEM_UPGRADE: at least one plugin on which the plugin is dependent requires SonarQube to be upgraded.</li></ul>Require 'Administer System' permission.
func (s *PluginsService) Available() (v *PluginsAvailableObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "plugins/available", nil)
if err != nil {
return
}
v = new(PluginsAvailableObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// CancelAll Cancels any operation pending on any plugin (install, update or uninstall)<br/>Requires user to be authenticated with Administer System permissions
func (s *PluginsService) CancelAll() (resp *http.Response, err error) {
req, err := s.client.NewRequest("POST", "plugins/cancel_all", nil)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PluginsInstallOption struct {
Key string `url:"key,omitempty"` // Description:"The key identifying the plugin to install",ExampleValue:""
}
// Install Installs the latest version of a plugin specified by its key.<br/>Plugin information is retrieved from Update Center.<br/>Requires user to be authenticated with Administer System permissions
func (s *PluginsService) Install(opt *PluginsInstallOption) (resp *http.Response, err error) {
err = s.ValidateInstallOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "plugins/install", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PluginsInstalledOption struct {
F string `url:"f,omitempty"` // Description:"Comma-separated list of the additional fields to be returned in response. No additional field is returned by default. Possible values are:<ul><li>category - category as defined in the Update Center. A connection to the Update Center is needed</li></lu>",ExampleValue:""
}
// Installed Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name.
func (s *PluginsService) Installed(opt *PluginsInstalledOption) (v *PluginsInstalledObject, resp *http.Response, err error) {
err = s.ValidateInstalledOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "plugins/installed", opt)
if err != nil {
return
}
v = new(PluginsInstalledObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Pending Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name.<br/>Require 'Administer System' permission.
func (s *PluginsService) Pending() (v *PluginsPendingObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "plugins/pending", nil)
if err != nil {
return
}
v = new(PluginsPendingObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type PluginsUninstallOption struct {
Key string `url:"key,omitempty"` // Description:"The key identifying the plugin to uninstall",ExampleValue:""
}
// Uninstall Uninstalls the plugin specified by its key.<br/>Requires user to be authenticated with Administer System permissions.
func (s *PluginsService) Uninstall(opt *PluginsUninstallOption) (resp *http.Response, err error) {
err = s.ValidateUninstallOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "plugins/uninstall", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type PluginsUpdateOption struct {
Key string `url:"key,omitempty"` // Description:"The key identifying the plugin to update",ExampleValue:""
}
// Update Updates a plugin specified by its key to the latest version compatible with the SonarQube instance.<br/>Plugin information is retrieved from Update Center.<br/>Requires user to be authenticated with Administer System permissions
func (s *PluginsService) Update(opt *PluginsUpdateOption) (resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "plugins/update", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
// Updates Lists plugins installed on the SonarQube instance for which at least one newer version is available, sorted by plugin name.<br/>Each newer version is listed, ordered from the oldest to the newest, with its own update/compatibility status.<br/>Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response.<br/>Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE].<br/>Require 'Administer System' permission.
func (s *PluginsService) Updates() (v *PluginsUpdatesObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "plugins/updates", nil)
if err != nil {
return
}
v = new(PluginsUpdatesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,156 @@
// Manage project analyses.
package sonargo
import "net/http"
type ProjectAnalysesService struct {
client *Client
}
type EventCatagory string
const (
VersionEventCatagory EventCatagory = "VERSION"
OtherEventCatagory EventCatagory = "OTHER"
QualityProfileEventCatagory EventCatagory = "QUALITY_PROFILE"
QualityGateEventCatagory EventCatagory = "QUALITY_GATE"
)
type Event struct {
Analysis string `json:"analysis,omitempty"`
Key string `json:"key,omitempty"`
Category EventCatagory `json:"category,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}
type ProjectAnalysesEventObject struct {
Event *Event `json:"event,omitempty"`
}
type Analysis struct {
Key string `json:"key,omitempty"`
Date string `json:"date,omitempty"`
Events []*Event `json:"events,omitempty"`
}
type ProjectAnalysesSearchObject struct {
Paging *Paging `json:"paging,omitempty"`
Analyses []*Analysis `json:"analyses,omitempty"`
}
type ProjectAnalysesCreateEventOption struct {
Analysis string `url:"analysis,omitempty"` // Description:"Analysis key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Category EventCatagory `url:"category,omitempty"` // Description:"Category",ExampleValue:""
Name string `url:"name,omitempty"` // Description:"Name",ExampleValue:"5.6"
}
// CreateEvent Create a project analysis event.<br>Only event of category 'VERSION' and 'OTHER' can be created.<br>Requires one of the following permissions:<ul> <li>'Administer System'</li> <li>'Administer' rights on the specified project</li></ul>
func (s *ProjectAnalysesService) CreateEvent(opt *ProjectAnalysesCreateEventOption) (v *ProjectAnalysesEventObject, resp *http.Response, err error) {
err = s.ValidateCreateEventOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_analyses/create_event", opt)
if err != nil {
return
}
v = new(ProjectAnalysesEventObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectAnalysesDeleteOption struct {
Analysis string `url:"analysis,omitempty"` // Description:"Analysis key",ExampleValue:"AU-TpxcA-iU5OvuD2FL1"
}
// Delete Delete a project analysis.<br>Requires one of the following permissions:<ul> <li>'Administer System'</li> <li>'Administer' rights on the project of the specified analysis</li></ul>
func (s *ProjectAnalysesService) Delete(opt *ProjectAnalysesDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_analyses/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectAnalysesDeleteEventOption struct {
Event string `url:"event,omitempty"` // Description:"Event key",ExampleValue:"AU-TpxcA-iU5OvuD2FLz"
}
// DeleteEvent Delete a project analysis event.<br>Only event of category 'VERSION' and 'OTHER' can be deleted.<br>Requires one of the following permissions:<ul> <li>'Administer System'</li> <li>'Administer' rights on the specified project</li></ul>
func (s *ProjectAnalysesService) DeleteEvent(opt *ProjectAnalysesDeleteEventOption) (resp *http.Response, err error) {
err = s.ValidateDeleteEventOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_analyses/delete_event", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectAnalysesSearchOption struct {
Category string `url:"category,omitempty"` // Description:"Event category. Filter analyses that have at least one event of the category specified.",ExampleValue:"OTHER"
From string `url:"from,omitempty"` // Description:"Filter analyses created after the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided",ExampleValue:"2013-05-01"
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
To string `url:"to,omitempty"` // Description:"Filter analyses created before the given date (inclusive). <br>Either a date (server timezone) or datetime can be provided",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
}
// Search Search a project analyses and attached events.<br>Requires the following permission: 'Browse' on the specified project
func (s *ProjectAnalysesService) Search(opt *ProjectAnalysesSearchOption) (v *ProjectAnalysesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_analyses/search", opt)
if err != nil {
return
}
v = new(ProjectAnalysesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectAnalysesUpdateEventOption struct {
Event string `url:"event,omitempty"` // Description:"Event key",ExampleValue:"AU-TpxcA-iU5OvuD2FL5"
Name string `url:"name,omitempty"` // Description:"New name",ExampleValue:"5.6"
}
// UpdateEvent Update a project analysis event.<br>Only events of category 'VERSION' and 'OTHER' can be updated.<br>Requires one of the following permissions:<ul> <li>'Administer System'</li> <li>'Administer' rights on the specified project</li></ul>
func (s *ProjectAnalysesService) UpdateEvent(opt *ProjectAnalysesUpdateEventOption) (v *ProjectAnalysesEventObject, resp *http.Response, err error) {
err = s.ValidateUpdateEventOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_analyses/update_event", opt)
if err != nil {
return
}
v = new(ProjectAnalysesEventObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,57 @@
// Generate badges based on quality gates or measures
package sonargo
import "net/http"
type ProjectBadgesService struct {
client *Client
}
type ProjectBadgesMeasureOption struct {
Branch string `url:"branch,omitempty"` // Description:"Branch key",ExampleValue:"feature/my_branch"
Metric string `url:"metric,omitempty"` // Description:"Metric key",ExampleValue:""
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
PullRequest string `url:"pullRequest,omitempty"` // Description:"Pull request id",ExampleValue:"5461"
}
// Measure Generate badge for project's measure as an SVG.<br/>Requires 'Browse' permission on the specified project.
func (s *ProjectBadgesService) Measure(opt *ProjectBadgesMeasureOption) (v *string, resp *http.Response, err error) {
err = s.ValidateMeasureOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_badges/measure", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectBadgesQualityGateOption struct {
Branch string `url:"branch,omitempty"` // Description:"Branch key",ExampleValue:"feature/my_branch"
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
PullRequest string `url:"pullRequest,omitempty"` // Description:"Pull request id",ExampleValue:"5461"
}
// QualityGate Generate badge for project's quality gate as an SVG.<br/>Requires 'Browse' permission on the specified project.
func (s *ProjectBadgesService) QualityGate(opt *ProjectBadgesQualityGateOption) (v *string, resp *http.Response, err error) {
err = s.ValidateQualityGateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_badges/quality_gate", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,94 @@
// Manage branch (only available when the Branch plugin is installed)
package sonargo
import "net/http"
type ProjectBranchesService struct {
client *Client
}
type ProjectBranchesListObject struct {
Branches []*Branch `json:"branches,omitempty"`
}
type Branch struct {
AnalysisDate string `json:"analysisDate,omitempty"`
IsMain bool `json:"isMain,omitempty"`
MergeBranch string `json:"mergeBranch,omitempty"`
Name string `json:"name,omitempty"`
Status *Status `json:"status,omitempty"`
Type string `json:"type,omitempty"`
}
type Status struct {
Bugs int64 `json:"bugs,omitempty"`
CodeSmells int64 `json:"codeSmells,omitempty"`
QualityGateStatus string `json:"qualityGateStatus,omitempty"`
Vulnerabilities int64 `json:"vulnerabilities,omitempty"`
}
type ProjectBranchesDeleteOption struct {
Branch string `url:"branch,omitempty"` // Description:"Name of the branch",ExampleValue:"branch1"
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// Delete Delete a non-main branch of a project.<br/>Requires 'Administer' rights on the specified project.
func (s *ProjectBranchesService) Delete(opt *ProjectBranchesDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_branches/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectBranchesListOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// List List the branches of a project.<br/>Requires 'Browse' or 'Execute analysis' rights on the specified project.
func (s *ProjectBranchesService) List(opt *ProjectBranchesListOption) (v *ProjectBranchesListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_branches/list", opt)
if err != nil {
return
}
v = new(ProjectBranchesListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectBranchesRenameOption struct {
Name string `url:"name,omitempty"` // Description:"New name of the main branch",ExampleValue:"branch1"
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// Rename Rename the main branch of a project.<br/>Requires 'Administer' permission on the specified project.
func (s *ProjectBranchesService) Rename(opt *ProjectBranchesRenameOption) (resp *http.Response, err error) {
err = s.ValidateRenameOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_branches/rename", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,92 @@
// Manage projects links.
package sonargo
import "net/http"
type ProjectLinksService struct {
client *Client
}
type ProjectLinksCreateObject struct {
Link *Link `json:"link,omitempty"`
}
type Link struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
Type string `json:"type,omitempty"`
}
type ProjectLinksSearchObject struct {
Links []*Link `json:"links,omitempty"`
}
type ProjectLinksCreateOption struct {
Name string `url:"name,omitempty"` // Description:"Link name",ExampleValue:"Custom"
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Url string `url:"url,omitempty"` // Description:"Link url",ExampleValue:"http://example.com"
}
// Create Create a new project link.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *ProjectLinksService) Create(opt *ProjectLinksCreateOption) (v *ProjectLinksCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_links/create", opt)
if err != nil {
return
}
v = new(ProjectLinksCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectLinksDeleteOption struct {
Id string `url:"id,omitempty"` // Description:"Link id",ExampleValue:"17"
}
// Delete Delete existing project link.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *ProjectLinksService) Delete(opt *ProjectLinksDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_links/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectLinksSearchOption struct {
ProjectId string `url:"projectId,omitempty"` // Description:"Project Id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project Key",ExampleValue:"my_project"
}
// Search List links of a project.<br>The 'projectId' or 'projectKey' must be provided.<br>Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li><li>'Browse' on the specified project</li></ul>
func (s *ProjectLinksService) Search(opt *ProjectLinksSearchOption) (v *ProjectLinksSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_links/search", opt)
if err != nil {
return
}
v = new(ProjectLinksSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,66 @@
// Manage pull request (only available when the Branch plugin is installed)
package sonargo
import "net/http"
type ProjectPullRequestsService struct {
client *Client
}
type ProjectPullRequestsListObject struct {
PullRequests []*PullRequest `json:"pullRequests,omitempty"`
}
type PullRequest struct {
AnalysisDate string `json:"analysisDate,omitempty"`
Base string `json:"base,omitempty"`
Branch string `json:"branch,omitempty"`
Key string `json:"key,omitempty"`
Status Status `json:"status,omitempty"`
Title string `json:"title,omitempty"`
URL string `json:"url,omitempty"`
}
type ProjectPullRequestsDeleteOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
PullRequest int `url:"pullRequest,omitempty"` // Description:"Pull request id",ExampleValue:"1543"
}
// Delete Delete a pull request.<br/>Requires 'Administer' rights on the specified project.
func (s *ProjectPullRequestsService) Delete(opt *ProjectPullRequestsDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_pull_requests/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectPullRequestsListOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// List List the pull requests of a project.<br/>One of the following permissions is required: <ul><li>'Browse' rights on the specified project</li><li>'Execute Analysis' rights on the specified project</li></ul>
func (s *ProjectPullRequestsService) List(opt *ProjectPullRequestsListOption) (v *ProjectPullRequestsListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_pull_requests/list", opt)
if err != nil {
return
}
v = new(ProjectPullRequestsListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,53 @@
// Manage project tags
package sonargo
import "net/http"
type ProjectTagsService struct {
client *Client
}
type ProjectTagsSearchOption struct {
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 100",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to tags that contain the supplied string.",ExampleValue:"off"
}
// Search Search tags
func (s *ProjectTagsService) Search(opt *ProjectTagsSearchOption) (v *IssuesTagsObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "project_tags/search", opt)
if err != nil {
return
}
v = new(IssuesTagsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectTagsSetOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Tags *string `url:"tags,omitempty"` // Description:"Comma-separated list of tags",ExampleValue:"finance, offshore"
}
// Set Set tags on a project.<br>Requires the following permission: 'Administer' rights on the specified project
func (s *ProjectTagsService) Set(opt *ProjectTagsSetOption) (resp *http.Response, err error) {
err = s.ValidateSetOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "project_tags/set", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,210 @@
// Manage project existence.
package sonargo
import "net/http"
type ProjectsService struct {
client *Client
}
const (
ProjectVisibilityPublic = "public"
ProjectVisibilityPrivate = "private"
)
type ProjectsBulkUpdateKeyObject struct {
Keys []*Key `json:"keys,omitempty"`
}
type Key struct {
Duplicate bool `json:"duplicate,omitempty"`
Key string `json:"key,omitempty"`
NewKey string `json:"newKey,omitempty"`
}
type Project struct {
CreationDate string `json:"creationDate,omitempty"`
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
Qualifier string `json:"qualifier,omitempty"`
UUID string `json:"uuid,omitempty"`
Visibility string `json:"visibility,omitempty"`
}
type ProjectsCreateObject struct {
Project *Project `json:"project,omitempty"`
}
type ProjectsBulkDeleteOption struct {
AnalyzedBefore string `url:"analyzedBefore,omitempty"` // Description:"Filter the projects for which last analysis is older than the given date (exclusive).<br> Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
OnProvisionedOnly string `url:"onProvisionedOnly,omitempty"` // Description:"Filter the projects that are provisioned",ExampleValue:""
ProjectIds string `url:"projectIds,omitempty"` // Description:"Comma-separated list of project ids. Only the 1'000 first ids are used. Others are silently ignored.",ExampleValue:"AU-Tpxb--iU5OvuD2FLy,AU-TpxcA-iU5OvuD2FLz"
Projects string `url:"projects,omitempty"` // Description:"Comma-separated list of project keys",ExampleValue:"my_project,another_project"
Q string `url:"q,omitempty"` // Description:"Limit to: <ul><li>component names that contain the supplied string</li><li>component keys that contain the supplied string</li></ul>",ExampleValue:"sonar"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers",ExampleValue:""
}
// BulkDelete Delete one or several projects.<br />Requires 'Administer System' permission.
func (s *ProjectsService) BulkDelete(opt *ProjectsBulkDeleteOption) (resp *http.Response, err error) {
err = s.ValidateBulkDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/bulk_delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectsBulkUpdateKeyOption struct {
DryRun string `url:"dryRun,omitempty"` // Description:"Simulate bulk update. No component key is updated.",ExampleValue:""
From string `url:"from,omitempty"` // Description:"String to match in components keys",ExampleValue:"_old"
Project string `url:"project,omitempty"` // Description:"Project or module key",ExampleValue:"my_old_project"
ProjectId string `url:"projectId,omitempty"` // Description:"Project or module ID",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
To string `url:"to,omitempty"` // Description:"String replacement in components keys",ExampleValue:"_new"
}
// BulkUpdateKey Bulk update a project or module key and all its sub-components keys. The bulk update allows to replace a part of the current key by another string on the current project and all its sub-modules.<br>It's possible to simulate the bulk update by setting the parameter 'dryRun' at true. No key is updated with a dry run.<br>Ex: to rename a project with key 'my_project' to 'my_new_project' and all its sub-components keys, call the WS with parameters:<ul> <li>project: my_project</li> <li>from: my_</li> <li>to: my_new_</li></ul>Either 'projectId' or 'project' must be provided.<br> Requires one of the following permissions: <ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *ProjectsService) BulkUpdateKey(opt *ProjectsBulkUpdateKeyOption) (v *ProjectsBulkUpdateKeyObject, resp *http.Response, err error) {
err = s.ValidateBulkUpdateKeyOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/bulk_update_key", opt)
if err != nil {
return
}
v = new(ProjectsBulkUpdateKeyObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectsCreateOption struct {
Branch string `url:"branch,omitempty"` // Description:"SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'",ExampleValue:"branch-5.0"
Name string `url:"name,omitempty"` // Description:"Name of the project",ExampleValue:"SonarQube"
Project string `url:"project,omitempty"` // Description:"Key of the project",ExampleValue:"my_project"
Visibility string `url:"visibility,omitempty"` // Description:"Whether the created project should be visible to everyone, or only specific user/groups.<br/>If no visibility is specified, the default project visibility of the organization will be used.",ExampleValue:""
}
// Create Create a project.<br/>Requires 'Create Projects' permission
func (s *ProjectsService) Create(opt *ProjectsCreateOption) (v *ProjectsCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/create", opt)
if err != nil {
return
}
v = new(ProjectsCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectsDeleteOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
ProjectId string `url:"projectId,omitempty"` // Description:"Project ID",ExampleValue:"ce4c03d6-430f-40a9-b777-ad877c00aa4d"
}
// Delete Delete a project.<br> Requires 'Administer System' permission or 'Administer' permission on the project.
func (s *ProjectsService) Delete(opt *ProjectsDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectsSearchOption struct {
AnalyzedBefore string `url:"analyzedBefore,omitempty"` // Description:"Filter the projects for which last analysis is older than the given date (exclusive).<br> Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
OnProvisionedOnly string `url:"onProvisionedOnly,omitempty"` // Description:"Filter the projects that are provisioned",ExampleValue:""
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
ProjectIds string `url:"projectIds,omitempty"` // Description:"Comma-separated list of project ids",ExampleValue:"AU-Tpxb--iU5OvuD2FLy,AU-TpxcA-iU5OvuD2FLz"
Projects string `url:"projects,omitempty"` // Description:"Comma-separated list of project keys",ExampleValue:"my_project,another_project"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to: <ul><li>component names that contain the supplied string</li><li>component keys that contain the supplied string</li></ul>",ExampleValue:"sonar"
Qualifiers string `url:"qualifiers,omitempty"` // Description:"Comma-separated list of component qualifiers. Filter the results with the specified qualifiers",ExampleValue:""
}
type ProjectSearchObject ComponentsSearchObject
// Search Search for projects or views to administrate them.<br>Requires 'System Administrator' permission
func (s *ProjectsService) Search(opt *ProjectsSearchOption) (v *ProjectSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "projects/search", opt)
if err != nil {
return
}
v = new(ProjectSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type ProjectsUpdateKeyOption struct {
From string `url:"from,omitempty"` // Description:"Project or module key",ExampleValue:"my_old_project"
ProjectId string `url:"projectId,omitempty"` // Description:"Project or module id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
To string `url:"to,omitempty"` // Description:"New component key",ExampleValue:"my_new_project"
}
// UpdateKey Update a project or module key and all its sub-components keys.<br>Either 'from' or 'projectId' must be provided.<br> Requires one of the following permissions: <ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li></ul>
func (s *ProjectsService) UpdateKey(opt *ProjectsUpdateKeyOption) (resp *http.Response, err error) {
err = s.ValidateUpdateKeyOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/update_key", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type ProjectsUpdateVisibilityOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
Visibility string `url:"visibility,omitempty"` // Description:"New visibility",ExampleValue:""
}
// UpdateVisibility Updates visibility of a project.<br>Requires 'Project administer' permission on the specified project
func (s *ProjectsService) UpdateVisibility(opt *ProjectsUpdateVisibilityOption) (resp *http.Response, err error) {
err = s.ValidateUpdateVisibilityOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "projects/update_visibility", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,436 @@
// Manage quality gates, including conditions and project association.
package sonargo
import "net/http"
type QualitygatesService struct {
client *Client
}
type QualityGatesCondition struct {
Error string `json:"error,omitempty"`
ID int `json:"id,omitempty"`
Metric string `json:"metric,omitempty"`
Op string `json:"op,omitempty"`
Warning string `json:"warning,omitempty"`
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org
Period string `url:"period,omitempty"` // Description:"Condition period. If not set, the absolute value is considered.",ExampleValue:"1"
}
type QualitygatesGetByProjectObject struct {
QualityGate *QualityGate `json:"qualityGate,omitempty"`
}
type QualityGate struct {
Default bool `json:"default,omitempty"`
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}
type QualitygatesListObject struct {
Actions *Actions `json:"actions,omitempty"`
Default int64 `json:"default,omitempty"`
Qualitygates []*QualityGateV2 `json:"qualitygates,omitempty"`
}
type Actions struct {
Create bool `json:"create,omitempty"`
AssociateProjects bool `json:"associateProjects,omitempty"`
Copy bool `json:"copy,omitempty"`
Delete bool `json:"delete,omitempty"`
Edit bool `json:"edit,omitempty"`
ManageConditions bool `json:"manageConditions,omitempty"`
Rename bool `json:"rename,omitempty"`
SetAsDefault bool `json:"setAsDefault,omitempty"`
}
type QualityGateV2 struct {
Actions *Actions `json:"actions,omitempty"`
Conditions []*QualityGatesCondition `json:"conditions,omitempty"`
ID int `json:"id,omitempty"`
IsBuiltIn bool `json:"isBuiltIn,omitempty"`
IsDefault bool `json:"isDefault,omitempty"`
Name string `json:"name,omitempty"`
}
type QualitygatesProjectStatusObject struct {
ProjectStatus *ProjectStatus `json:"projectStatus,omitempty"`
}
type Condition struct {
ActualValue string `json:"actualValue,omitempty"`
Comparator string `json:"comparator,omitempty"`
ErrorThreshold string `json:"errorThreshold,omitempty"`
MetricKey string `json:"metricKey,omitempty"`
PeriodIndex int64 `json:"periodIndex,omitempty"`
Status string `json:"status,omitempty"`
WarningThreshold string `json:"warningThreshold,omitempty"`
}
type ProjectStatus struct {
Conditions []*Condition `json:"conditions,omitempty"`
IgnoredConditions bool `json:"ignoredConditions,omitempty"`
Periods []*Period `json:"periods,omitempty"`
Status string `json:"status,omitempty"`
}
type QualitygatesSearchObject struct {
Paging *Paging `json:"paging,omitempty"`
More bool `json:"more,omitempty"`
Results []*Result `json:"results,omitempty"`
}
type Result struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Selected bool `json:"selected,omitempty"`
}
type QualitygatesCopyOption struct {
Id int `url:"id,omitempty"` // Description:"The ID of the source quality gate",ExampleValue:"1"
Name string `url:"name,omitempty"` // Description:"The name of the quality gate to create",ExampleValue:"My Quality Gate"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
}
// Copy Copy a Quality Gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) Copy(opt *QualitygatesCopyOption) (v *QualityGate, resp *http.Response, err error) {
err = s.ValidateCopyOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/copy", opt)
if err != nil {
return
}
v = new(QualityGate)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type QualitygatesCreateOption struct {
Name string `url:"name,omitempty"` // Description:"The name of the quality gate to create",ExampleValue:"My Quality Gate"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
}
// Create Create a Quality Gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) Create(opt *QualitygatesCreateOption) (v *QualityGate, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/create", opt)
if err != nil {
return
}
v = new(QualityGate)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesCreateConditionOption struct {
Error string `url:"error,omitempty"` // Description:"Condition error threshold",ExampleValue:"10"
GateId int `url:"gateId,omitempty"` // Description:"ID of the quality gate",ExampleValue:"1"
Metric string `url:"metric,omitempty"` // Description:"Condition metric",ExampleValue:"blocker_violations"
Op string `url:"op,omitempty"` // Description:"Condition operator:<br/><ul><li>EQ = equals</li><li>NE = is not</li><li>LT = is lower than</li><li>GT = is greater than</li></ui>",ExampleValue:"EQ"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
Period string `url:"period,omitempty"` // Description:"Condition period. If not set, the absolute value is considered.",ExampleValue:""
Warning string `url:"warning,omitempty"` // Description:"Condition warning threshold",ExampleValue:"5"
}
// CreateCondition Add a new condition to a quality gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) CreateCondition(opt *QualitygatesCreateConditionOption) (v *QualityGatesCondition, resp *http.Response, err error) {
err = s.ValidateCreateConditionOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/create_condition", opt)
if err != nil {
return
}
v = new(QualityGatesCondition)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesDeleteConditionOption struct {
ConditionID int `url:"id,omitempty"` // Description:"Condition ID",ExampleValue:"2"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
}
// DeleteCondition Delete a condition from a quality gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) DeleteCondition(opt *QualitygatesDeleteConditionOption) (resp *http.Response, err error) {
err = s.ValidateDeleteConditionOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/delete_condition", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualitygatesDeselectOption struct {
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// Deselect Remove the association of a project from a quality gate.<br>Requires one of the following permissions:<ul><li>'Administer Quality Gates'</li><li>'Administer' rights on the project</li></ul>
func (s *QualitygatesService) Deselect(opt *QualitygatesDeselectOption) (resp *http.Response, err error) {
err = s.ValidateDeselectOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/deselect", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualitygatesDestroyOption struct {
Id int `url:"id,omitempty"` // Description:"ID of the quality gate to delete",ExampleValue:"1"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
}
// Destroy Delete a Quality Gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) Destroy(opt *QualitygatesDestroyOption) (resp *http.Response, err error) {
err = s.ValidateDestroyOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/destroy", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualitygatesGetByProjectOption struct {
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// GetByProject Get the quality gate of a project.<br />Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li><li>'Browse' on the specified project</li></ul>
func (s *QualitygatesService) GetByProject(opt *QualitygatesGetByProjectOption) (v *QualitygatesGetByProjectObject, resp *http.Response, err error) {
err = s.ValidateGetByProjectOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualitygates/get_by_project", opt)
if err != nil {
return
}
v = new(QualitygatesGetByProjectObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesListOption struct {
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
}
// List Get a list of quality gates
func (s *QualitygatesService) List(opt *QualitygatesListOption) (v *QualitygatesListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualitygates/list", opt)
if err != nil {
return
}
v = new(QualitygatesListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesProjectStatusOption struct {
AnalysisId string `url:"analysisId,omitempty"` // Description:"Analysis id",ExampleValue:"AU-TpxcA-iU5OvuD2FL1"
ProjectId string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// ProjectStatus Get the quality gate status of a project or a Compute Engine task.<br />Either 'analysisId', 'projectId' or 'projectKey' must be provided<br />The different statuses returned are: OK, WARN, ERROR, NONE. The NONE status is returned when there is no quality gate associated with the analysis.<br />Returns an HTTP code 404 if the analysis associated with the task is not found or does not exist.<br />Requires one of the following permissions:<ul><li>'Administer System'</li><li>'Administer' rights on the specified project</li><li>'Browse' on the specified project</li></ul>
func (s *QualitygatesService) ProjectStatus(opt *QualitygatesProjectStatusOption) (v *QualitygatesProjectStatusObject, resp *http.Response, err error) {
err = s.ValidateProjectStatusOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualitygates/project_status", opt)
if err != nil {
return
}
v = new(QualitygatesProjectStatusObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesRenameOption QualitygatesCopyOption
// Rename Rename a Quality Gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) Rename(opt *QualitygatesRenameOption) (v *QualityGate, resp *http.Response, err error) {
err = s.ValidateRenameOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/rename", opt)
if err != nil {
return
}
v = new(QualityGate)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type QualitygatesSearchOption struct {
GateId int `url:"gateId,omitempty"` // Description:"Quality Gate ID",ExampleValue:"1"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
Page string `url:"page,omitempty"` // Description:"Page number",ExampleValue:"2"
PageSize string `url:"pageSize,omitempty"` // Description:"Page size",ExampleValue:"10"
Query string `url:"query,omitempty"` // Description:"To search for projects containing this string. If this parameter is set, "selected" is set to "all".",ExampleValue:"abc"
Selected string `url:"selected,omitempty"` // Description:"Depending on the value, show only selected items (selected=selected), deselected items (selected=deselected), or all items with their selection status (selected=all).",ExampleValue:""
}
// Search Search for projects associated (or not) to a quality gate.<br/>Only authorized projects for current user will be returned.
func (s *QualitygatesService) Search(opt *QualitygatesSearchOption) (v *QualitygatesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualitygates/search", opt)
if err != nil {
return
}
v = new(QualitygatesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesSelectOption struct {
GateId int `url:"gateId,omitempty"` // Description:"Quality gate id",ExampleValue:"1"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
ProjectKey string `url:"projectKey,omitempty"` // Description:"Project key",ExampleValue:"my_project"
ProjectID string `url:"projectId,omitempty"` // Description:"Project id",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Select Associate a project to a quality gate.<br>The 'projectId' or 'projectKey' must be provided.<br>Project id as a numeric value is deprecated since 6.1. Please use the id similar to 'AU-TpxcA-iU5OvuD2FLz'.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) Select(opt *QualitygatesSelectOption) (resp *http.Response, err error) {
err = s.ValidateSelectOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/select", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualitygatesSetAsDefaultOption QualitygatesDestroyOption
// SetAsDefault Set a quality gate as the default quality gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) SetAsDefault(opt *QualitygatesSetAsDefaultOption) (resp *http.Response, err error) {
err = s.ValidateSetAsDefaultOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/set_as_default", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualitygatesShowOption QualitygatesRenameOption
// Show Display the details of a quality gate
func (s *QualitygatesService) Show(opt *QualitygatesShowOption) (v *QualityGateV2, resp *http.Response, err error) {
err = s.ValidateShowOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualitygates/show", opt)
if err != nil {
return
}
v = new(QualityGateV2)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualitygatesUpdateConditionOption struct {
Error string `url:"error,omitempty"` // Description:"Condition error threshold",ExampleValue:"10"
Id int `url:"id,omitempty"` // Description:"Condition ID",ExampleValue:"10"
Metric string `url:"metric,omitempty"` // Description:"Condition metric",ExampleValue:"blocker_violations"
Op string `url:"op,omitempty"` // Description:"Condition operator:<br/><ul><li>EQ = equals</li><li>NE = is not</li><li>LT = is lower than</li><li>GT = is greater than</li></ui>",ExampleValue:"EQ"
Organization string `url:"organization,omitempty"` // Description:"Organization key. If no organization is provided, the default organization is used.",ExampleValue:"my-org"
Period string `url:"period,omitempty"` // Description:"Condition period. If not set, the absolute value is considered.",ExampleValue:""
Warning string `url:"warning,omitempty"` // Description:"Condition warning threshold",ExampleValue:"5"
}
// UpdateCondition Update a condition attached to a quality gate.<br>Requires the 'Administer Quality Gates' permission.
func (s *QualitygatesService) UpdateCondition(opt *QualitygatesUpdateConditionOption) (v *QualityGatesCondition, resp *http.Response, err error) {
err = s.ValidateUpdateConditionOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualitygates/update_condition", opt)
if err != nil {
return
}
v = new(QualityGatesCondition)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,600 @@
// Manage quality profiles.
package sonargo
import (
"net/http"
)
type QualityProfilesService struct {
client *Client
}
type QualityProfile struct {
Actions *Actions `json:"actions,omitempty"`
ActiveRuleCount int64 `json:"activeRuleCount,omitempty"`
IsBuiltIn bool `json:"isBuiltIn,omitempty"`
IsDefault bool `json:"isDefault,omitempty"`
IsInherited bool `json:"isInherited,omitempty"`
Key string `json:"key,omitempty"`
Language string `json:"language,omitempty"`
LanguageName string `json:"languageName,omitempty"`
Name string `json:"name,omitempty"`
OverridingRuleCount int64 `json:"overridingRuleCount,omitempty"`
Organization string `json:"organization,omitempty"`
Parent string `json:"parent,omitempty"`
ParentKey string `json:"parentKey,omitempty"`
ActiveDeprecatedRuleCount int `json:"activeDeprecatedRuleCount,omitempty"`
RulesUpdatedAt string `json:"rulesUpdatedAt,omitempty"`
UserUpdatedAt string `json:"userUpdatedAt,omitempty"`
LastUsed string `json:"lastUsed,omitempty"`
ProjectCount int `json:"projectCount,omitempty"`
}
type QualityProfilesChangelogObject struct {
Events []*QualityProfilesEvent `json:"events,omitempty"`
P int64 `json:"p,omitempty"`
Ps int64 `json:"ps,omitempty"`
Total int64 `json:"total,omitempty"`
}
type QualityProfilesEvent struct {
Action string `json:"action,omitempty"`
AuthorLogin string `json:"authorLogin,omitempty"`
AuthorName string `json:"authorName,omitempty"`
Date string `json:"date,omitempty"`
Params interface{} `json:"params,omitempty"`
RuleKey string `json:"ruleKey,omitempty"`
RuleName string `json:"ruleName,omitempty"`
}
type QualityProfilesActiveRulesObject struct {
Succeeded int `json:"succeeded"`
Failed int `json:"failed"`
Errors []struct {
Msg string `json:"msg"`
} `json:"errors"`
}
type QualityProfilesDeactiveRulesObject QualityProfilesActiveRulesObject
type QualityProfilesCreateObject struct {
Profile *QualityProfile `json:"profile,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
type ExportImporter struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
Languages []string `json:"languages,omitempty"`
}
type QualityProfilesExportersObject struct {
Exporters []*ExportImporter `json:"exporters,omitempty"`
}
type QualityProfilesImportersObject struct {
Importers []*ExportImporter `json:"importers,omitempty"`
}
type QualityProfilesInheritanceObject struct {
Ancestors []*QualityProfile `json:"ancestors,omitempty"`
Children []*QualityProfile `json:"children,omitempty"`
Profile QualityProfile `json:"profile,omitempty"`
}
type QualityProfilesSearchObject struct {
Actions *Actions `json:"actions,omitempty"`
Profiles []*QualityProfile `json:"profiles,omitempty"`
}
type QualityProfilesActivateRuleOption struct {
Key string `url:"key,omitempty"` // Description:"Quality Profile key. Can be obtained through <code>api/qualityprofiles/search</code>",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Params string `url:"params,omitempty"` // Description:"Parameters as semi-colon list of <code>key=value</code>. Ignored if parameter reset is true.",ExampleValue:"params=key1=v1;key2=v2"
Reset string `url:"reset,omitempty"` // Description:"Reset severity and parameters of activated rule. Set the values defined on parent profile or from rule default values.",ExampleValue:""
Rule string `url:"rule,omitempty"` // Description:"Rule key",ExampleValue:"squid:AvoidCycles"
Severity string `url:"severity,omitempty"` // Description:"Severity. Ignored if parameter reset is true.",ExampleValue:""
}
// ActivateRule Activate a rule on a Quality Profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) ActivateRule(opt *QualityProfilesActivateRuleOption) (resp *http.Response, err error) {
err = s.ValidateActivateRuleOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/activate_rule", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesActivateRulesOption struct {
Activation string `url:"activation,omitempty"` // Description:"Filter rules that are activated or deactivated on the selected Quality profile. Ignored if the parameter 'qprofile' is not set.",ExampleValue:""
ActiveSeverities string `url:"active_severities,omitempty"` // Description:"Comma-separated list of activation severities, i.e the severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
AvailableSince string `url:"available_since,omitempty"` // Description:"Filters rules added since date. Format is yyyy-MM-dd",ExampleValue:"2014-06-22"
Inheritance string `url:"inheritance,omitempty"` // Description:"Comma-separated list of values of inheritance for a rule within a quality profile. Used only if the parameter 'activation' is set.",ExampleValue:"INHERITED,OVERRIDES"
IsTemplate string `url:"is_template,omitempty"` // Description:"Filter template rules",ExampleValue:""
Languages string `url:"languages,omitempty"` // Description:"Comma-separated list of languages",ExampleValue:"java,js"
Q string `url:"q,omitempty"` // Description:"UTF-8 search query",ExampleValue:"xpath"
Qprofile string `url:"qprofile,omitempty"` // Description:"Quality profile key to filter on. Used only if the parameter 'activation' is set.",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Repositories string `url:"repositories,omitempty"` // Description:"Comma-separated list of repositories",ExampleValue:"checkstyle,findbugs"
RuleKey string `url:"rule_key,omitempty"` // Description:"Key of rule to search for",ExampleValue:"squid:S001"
S string `url:"s,omitempty"` // Description:"Sort field",ExampleValue:"name"
Severities string `url:"severities,omitempty"` // Description:"Comma-separated list of default severities. Not the same than severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Statuses string `url:"statuses,omitempty"` // Description:"Comma-separated list of status codes",ExampleValue:"READY"
Tags string `url:"tags,omitempty"` // Description:"Comma-separated list of tags. Returned rules match any of the tags (OR operator)",ExampleValue:"security,java8"
TargetKey string `url:"targetKey,omitempty"` // Description:"Quality Profile key on which the rule activation is done. To retrieve a quality profile key please see <code>api/qualityprofiles/search</code>",ExampleValue:"AU-TpxcA-iU5OvuD2FL0"
TargetSeverity string `url:"targetSeverity,omitempty"` // Description:"Severity to set on the activated rules",ExampleValue:""
TemplateKey string `url:"template_key,omitempty"` // Description:"Key of the template rule to filter on. Used to search for the custom rules based on this template.",ExampleValue:"java:S001"
Types string `url:"types,omitempty"` // Description:"Comma-separated list of types. Returned rules match any of the tags (OR operator)",ExampleValue:"BUG"
}
// ActivateRules Bulk-activate rules on one quality profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) ActivateRules(opt *QualityProfilesActivateRulesOption) (v *QualityProfilesActiveRulesObject, resp *http.Response, err error) {
err = s.ValidateActivateRulesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/activate_rules", opt)
if err != nil {
return
}
v = new(QualityProfilesActiveRulesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type QualityProfilesAddProjectOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
ProjectUuid string `url:"projectUuid,omitempty"` // Description:"Project ID. Either this parameter or 'project' must be set.",ExampleValue:"AU-TpxcA-iU5OvuD2FL5"
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
Organization string `json:"organization,omitempty"`
}
// AddProject Associate a project with a quality profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li> <li>Administer right on the specified project</li></ul>
func (s *QualityProfilesService) AddProject(opt *QualityProfilesAddProjectOption) (resp *http.Response, err error) {
err = s.ValidateAddProjectOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/add_project", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesBackupOption struct {
ProfileKey string `url:"profileKey,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
}
// Backup Backup a quality profile in XML form. The exported profile can be restored through api/qualityprofiles/restore.
func (s *QualityProfilesService) Backup(opt *QualityProfilesBackupOption) (v *string, resp *http.Response, err error) {
err = s.ValidateBackupOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/backup", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
// b := new(bytes.Buffer)
// b.ReadFrom(resp.Body)
// *v = b.String()
return
}
type QualityProfilesChangeParentOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
ParentKey string `url:"parentKey,omitempty"` // Description:"New parent profile key.<br> If no profile is provided, the inheritance link with current parent profile (if any) is broken, which deactivates all rules which come from the parent and are not overridden.",ExampleValue:"AU-TpxcA-iU5OvuD2FLz"
ParentQualityProfile string `url:"parentQualityProfile,omitempty"` // Description:"Quality profile name. If this parameter is set, 'parentKey' must not be set and 'language' must be set to disambiguate.",ExampleValue:"Sonar way"
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
}
// ChangeParent Change a quality profile's parent.<br>Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) ChangeParent(opt *QualityProfilesChangeParentOption) (resp *http.Response, err error) {
err = s.ValidateChangeParentOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/change_parent", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesChangelogOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
Since string `url:"since,omitempty"` // Description:"Start date for the changelog. <br>Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
To string `url:"to,omitempty"` // Description:"End date for the changelog. <br>Either a date (server timezone) or datetime can be provided.",ExampleValue:"2017-10-19 or 2017-10-19T13:00:00+0200"
}
// Changelog Get the history of changes on a quality profile: rule activation/deactivation, change in parameters/severity. Events are ordered by date in descending order (most recent first).
func (s *QualityProfilesService) Changelog(opt *QualityProfilesChangelogOption) (v *QualityProfilesChangelogObject, resp *http.Response, err error) {
err = s.ValidateChangelogOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/changelog", opt)
if err != nil {
return
}
v = new(QualityProfilesChangelogObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesCopyOption struct {
FromKey string `url:"fromKey,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ToName string `url:"toName,omitempty"` // Description:"Name for the new quality profile.",ExampleValue:"My Sonar way"
}
// Copy Copy a quality profile.<br> Requires to be logged in and the 'Administer Quality Profiles' permission.
func (s *QualityProfilesService) Copy(opt *QualityProfilesCopyOption) (v *QualityProfile, resp *http.Response, err error) {
err = s.ValidateCopyOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/copy", opt)
if err != nil {
return
}
v = new(QualityProfile)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesCreateOption struct {
BackupSonarlintVsCsFake string `url:"backup_sonarlint-vs-cs-fake,omitempty"` // Description:"A configuration file for Technical importer for the MSBuild SonarQube Scanner.",ExampleValue:""
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:"js"
Name string `url:"name,omitempty"` // Description:"Quality profile name",ExampleValue:"My Sonar way"
Organization string `url:"organization,omitempty"`
}
// Create Create a quality profile.<br>Requires to be logged in and the 'Administer Quality Profiles' permission.
func (s *QualityProfilesService) Create(opt *QualityProfilesCreateOption) (v *QualityProfilesCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/create", opt)
if err != nil {
return
}
v = new(QualityProfilesCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesDeactivateRuleOption struct {
Key string `url:"key,omitempty"` // Description:"Quality Profile key. Can be obtained through <code>api/qualityprofiles/search</code>",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Rule string `url:"rule,omitempty"` // Description:"Rule key",ExampleValue:"squid:AvoidCycles"
}
// DeactivateRule Deactivate a rule on a quality profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) DeactivateRule(opt *QualityProfilesDeactivateRuleOption) (resp *http.Response, err error) {
err = s.ValidateDeactivateRuleOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/deactivate_rule", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesDeactivateRulesOption struct {
Activation string `url:"activation,omitempty"` // Description:"Filter rules that are activated or deactivated on the selected Quality profile. Ignored if the parameter 'qprofile' is not set.",ExampleValue:""
ActiveSeverities string `url:"active_severities,omitempty"` // Description:"Comma-separated list of activation severities, i.e the severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
AvailableSince string `url:"available_since,omitempty"` // Description:"Filters rules added since date. Format is yyyy-MM-dd",ExampleValue:"2014-06-22"
Inheritance string `url:"inheritance,omitempty"` // Description:"Comma-separated list of values of inheritance for a rule within a quality profile. Used only if the parameter 'activation' is set.",ExampleValue:"INHERITED,OVERRIDES"
IsTemplate string `url:"is_template,omitempty"` // Description:"Filter template rules",ExampleValue:""
Languages string `url:"languages,omitempty"` // Description:"Comma-separated list of languages",ExampleValue:"java,js"
Q string `url:"q,omitempty"` // Description:"UTF-8 search query",ExampleValue:"xpath"
Qprofile string `url:"qprofile,omitempty"` // Description:"Quality profile key to filter on. Used only if the parameter 'activation' is set.",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Repositories string `url:"repositories,omitempty"` // Description:"Comma-separated list of repositories",ExampleValue:"checkstyle,findbugs"
RuleKey string `url:"rule_key,omitempty"` // Description:"Key of rule to search for",ExampleValue:"squid:S001"
S string `url:"s,omitempty"` // Description:"Sort field",ExampleValue:"name"
Severities string `url:"severities,omitempty"` // Description:"Comma-separated list of default severities. Not the same than severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Statuses string `url:"statuses,omitempty"` // Description:"Comma-separated list of status codes",ExampleValue:"READY"
Tags string `url:"tags,omitempty"` // Description:"Comma-separated list of tags. Returned rules match any of the tags (OR operator)",ExampleValue:"security,java8"
TargetKey string `url:"targetKey,omitempty"` // Description:"Quality Profile key on which the rule deactivation is done. To retrieve a profile key please see <code>api/qualityprofiles/search</code>",ExampleValue:"AU-TpxcA-iU5OvuD2FL1"
TemplateKey string `url:"template_key,omitempty"` // Description:"Key of the template rule to filter on. Used to search for the custom rules based on this template.",ExampleValue:"java:S001"
Types string `url:"types,omitempty"` // Description:"Comma-separated list of types. Returned rules match any of the tags (OR operator)",ExampleValue:"BUG"
}
// DeactivateRules Bulk deactivate rules on Quality profiles.<br>Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) DeactivateRules(opt *QualityProfilesDeactivateRulesOption) (v *QualityProfilesDeactiveRulesObject, resp *http.Response, err error) {
err = s.ValidateDeactivateRulesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/deactivate_rules", opt)
if err != nil {
return
}
v = new(QualityProfilesDeactiveRulesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type QualityProfilesDeleteOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
}
// Delete Delete a quality profile and all its descendants. The default quality profile cannot be deleted.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) Delete(opt *QualityProfilesDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesExportOption struct {
ExporterKey string `url:"exporterKey,omitempty"` // Description:"Output format. If left empty, the same format as api/qualityprofiles/backup is used. Possible values are described by api/qualityprofiles/exporters.",ExampleValue:""
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:"py"
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name to export. If left empty, the default profile for the language is exported.",ExampleValue:"My Sonar way"
}
// Export Export a quality profile.
func (s *QualityProfilesService) Export(opt *QualityProfilesExportOption) (v *string, resp *http.Response, err error) {
err = s.ValidateExportOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/export", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Exporters Lists available profile export formats.
func (s *QualityProfilesService) Exporters() (v *QualityProfilesExportersObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "qualityprofiles/exporters", nil)
if err != nil {
return
}
v = new(QualityProfilesExportersObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Importers List supported importers.
func (s *QualityProfilesService) Importers() (v *QualityProfilesImportersObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "qualityprofiles/importers", nil)
if err != nil {
return
}
v = new(QualityProfilesImportersObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesInheritanceOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
}
// Inheritance Show a quality profile's ancestors and children.
func (s *QualityProfilesService) Inheritance(opt *QualityProfilesInheritanceOption) (v *QualityProfilesInheritanceObject, resp *http.Response, err error) {
err = s.ValidateInheritanceOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/inheritance", opt)
if err != nil {
return
}
v = new(QualityProfilesInheritanceObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesProjectsOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to projects that contain the supplied string.",ExampleValue:"sonar"
Selected string `url:"selected,omitempty"` // Description:"Depending on the value, show only selected items (selected=selected), deselected items (selected=deselected), or all items with their selection status (selected=all).",ExampleValue:""
}
// Projects List projects with their association status regarding a quality profile
func (s *QualityProfilesService) Projects(opt *QualityProfilesProjectsOption) (v *QualitygatesSearchObject, resp *http.Response, err error) {
err = s.ValidateProjectsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/projects", opt)
if err != nil {
return
}
v = new(QualitygatesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesRemoveProjectOption QualityProfilesAddProjectOption
// RemoveProject Remove a project's association with a quality profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li> <li>Administer right on the specified project</li></ul>
func (s *QualityProfilesService) RemoveProject(opt *QualityProfilesRemoveProjectOption) (resp *http.Response, err error) {
err = s.ValidateRemoveProjectOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/remove_project", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesRenameOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Name string `url:"name,omitempty"` // Description:"New quality profile name",ExampleValue:"My Sonar way"
}
// Rename Rename a quality profile.<br> Requires one of the following permissions:<ul> <li>'Administer Quality Profiles'</li> <li>Edit right on the specified quality profile</li></ul>
func (s *QualityProfilesService) Rename(opt *QualityProfilesRenameOption) (resp *http.Response, err error) {
err = s.ValidateRenameOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/rename", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesRestoreOption struct {
Backup string `url:"backup,omitempty"` // Description:"A profile backup file in XML format, as generated by api/qualityprofiles/backup or the former api/profiles/backup.",ExampleValue:""
}
// Restore Restore a quality profile using an XML file. The restored profile name is taken from the backup file, so if a profile with the same name and language already exists, it will be overwritten.<br> Requires to be logged in and the 'Administer Quality Profiles' permission.
func (s *QualityProfilesService) Restore(opt *QualityProfilesRestoreOption) (resp *http.Response, err error) {
err = s.ValidateRestoreOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/restore", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type QualityProfilesSearchOption struct {
Defaults string `url:"defaults,omitempty"` // Description:"If set to true, return only the quality profiles marked as default for each language",ExampleValue:""
Language string `url:"language,omitempty"` // Description:"Language key. If provided, only profiles for the given language are returned.",ExampleValue:""
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"SonarQube Way"
}
// Search Search quality profiles
func (s *QualityProfilesService) Search(opt *QualityProfilesSearchOption) (v *QualityProfilesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "qualityprofiles/search", opt)
if err != nil {
return
}
v = new(QualityProfilesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type QualityProfilesSetDefaultOption struct {
Key string `url:"key,omitempty"` // Description:"Quality profile key",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Language string `url:"language,omitempty"` // Description:"Quality profile language",ExampleValue:""
QualityProfile string `url:"qualityProfile,omitempty"` // Description:"Quality profile name",ExampleValue:"Sonar way"
}
// SetDefault Select the default profile for a given language.<br> Requires to be logged in and the 'Administer Quality Profiles' permission.
func (s *QualityProfilesService) SetDefault(opt *QualityProfilesSetDefaultOption) (resp *http.Response, err error) {
err = s.ValidateSetDefaultOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "qualityprofiles/set_default", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,291 @@
// Get and update some details of automatic rules, and manage custom rules.
package sonargo
import "net/http"
type RulesService struct {
client *Client
}
type Rule struct {
Key string `json:"key,omitempty"`
Repo string `json:"repo,omitempty"`
Name string `json:"name,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
HTMLDesc string `json:"htmlDesc,omitempty"`
MdDesc string `json:"mdDesc,omitempty"`
Severity string `json:"severity,omitempty"`
Status string `json:"status,omitempty"`
IsTemplate bool `json:"isTemplate,omitempty"`
TemplateKey string `json:"templateKey,omitempty"`
Tags []string `json:"tags,omitempty"`
SysTags []string `json:"sysTags,omitempty"`
Lang string `json:"lang,omitempty"`
LangName string `json:"langName,omitempty"`
DebtOverloaded bool `json:"debtOverloaded,omitempty"`
RemFnOverloaded bool `json:"remFnOverloaded,omitempty"`
Params []*RuleParam `json:"params,omitempty"`
Scope string `json:"scope,omitempty"`
IsExternal bool `json:"isExternal,omitempty"`
Type string `json:"type,omitempty"`
}
type RuleParam struct {
DefaultValue string `json:"defaultValue,omitempty"`
Key string `json:"key,omitempty"`
HTMLDesc string `json:"htmlDesc,omitempty"`
Type string `json:"type,omitempty"`
}
type RulesRepositoriesObject struct {
Repositories []*Repositorie `json:"repositories,omitempty"`
}
type Repositorie struct {
Key string `json:"key,omitempty"`
Language string `json:"language,omitempty"`
Name string `json:"name,omitempty"`
}
type RuleCreateObject struct {
Rule *Rule `json:"rule,omitempty"`
}
type RulesSearchObject struct {
Actives *Actives `json:"actives,omitempty"`
Facets []*Facet `json:"facets,omitempty"`
P int64 `json:"p,omitempty"`
Ps int64 `json:"ps,omitempty"`
Rules []*Rule `json:"rules,omitempty"`
Total int64 `json:"total,omitempty"`
}
type RuleUpdateObject RuleCreateObject
type Actives struct {
SquidClassCyclomaticComplexity []*SquidClassCyclomaticComplexity `json:"squid:ClassCyclomaticComplexity,omitempty"`
SquidMethodCyclomaticComplexity []*SquidClassCyclomaticComplexity `json:"squid:MethodCyclomaticComplexity,omitempty"`
Squid_S1067 []*SquidClassCyclomaticComplexity `json:"squid:S1067,omitempty"`
}
type Facet struct {
Name string `json:"name,omitempty"`
Property string `json:"property,omitempty"`
Values []*FacetValue `json:"values,omitempty"`
}
type SquidParam struct {
Key string `json:"key,omitempty"`
Value string `json:"value,omitempty"`
}
type SquidClassCyclomaticComplexity struct {
Inherit string `json:"inherit,omitempty"`
Params []*SquidParam `json:"params,omitempty"`
QProfile string `json:"qProfile,omitempty"`
Severity string `json:"severity,omitempty"`
}
type FacetValue struct {
Count int64 `json:"count,omitempty"`
Val string `json:"val,omitempty"`
}
type RulesShowObject struct {
Actives []*SquidClassCyclomaticComplexity `json:"actives,omitempty"`
Rule *Rule `json:"rule,omitempty"`
}
type RulesCreateOption struct {
CustomKey string `url:"custom_key,omitempty"` // Description:"Key of the custom rule",ExampleValue:"Todo_should_not_be_used"
ManualKey string `url:"manual_key,omitempty"` // Description:"Manual rules are no more supported. This parameter is ignored",ExampleValue:"Error_handling"
MarkdownDescription string `url:"markdown_description,omitempty"` // Description:"Rule description",ExampleValue:"Description of my custom rule"
Name string `url:"name,omitempty"` // Description:"Rule name",ExampleValue:"My custom rule"
Params string `url:"params,omitempty"` // Description:"Parameters as semi-colon list of <key>=<value>, for example 'params=key1=v1;key2=v2' (Only for custom rule)",ExampleValue:""
PreventReactivation string `url:"prevent_reactivation,omitempty"` // Description:"If set to true and if the rule has been deactivated (status 'REMOVED'), a status 409 will be returned",ExampleValue:""
Severity string `url:"severity,omitempty"` // Description:"Rule severity",ExampleValue:""
Status string `url:"status,omitempty"` // Description:"Rule status",ExampleValue:""
TemplateKey string `url:"template_key,omitempty"` // Description:"Key of the template rule in order to create a custom rule (mandatory for custom rule)",ExampleValue:"java:XPath"
Type string `url:"type,omitempty"` // Description:"Rule type",ExampleValue:""
}
// Create Create a custom rule.<br>Requires the 'Administer Quality Profiles' permission
func (s *RulesService) Create(opt *RulesCreateOption) (v *RuleCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "rules/create", opt)
if err != nil {
return
}
v = new(RuleCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type RulesDeleteOption struct {
Key string `url:"key,omitempty"` // Description:"Rule key",ExampleValue:"squid:XPath_1402065390816"
}
// Delete Delete custom rule.<br/>Requires the 'Administer Quality Profiles' permission
func (s *RulesService) Delete(opt *RulesDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "rules/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type RulesRepositoriesOption struct {
Language string `url:"language,omitempty"` // Description:"A language key; if provided, only repositories for the given language will be returned",ExampleValue:"java"
Q string `url:"q,omitempty"` // Description:"A pattern to match repository keys/names against",ExampleValue:"squid"
}
// Repositories List available rule repositories
func (s *RulesService) Repositories(opt *RulesRepositoriesOption) (v *RulesRepositoriesObject, resp *http.Response, err error) {
err = s.ValidateRepositoriesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "rules/repositories", opt)
if err != nil {
return
}
v = new(RulesRepositoriesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type RulesSearchOption struct {
Activation string `url:"activation,omitempty"` // Description:"Filter rules that are activated or deactivated on the selected Quality profile. Ignored if the parameter 'qprofile' is not set.",ExampleValue:""
ActiveSeverities string `url:"active_severities,omitempty"` // Description:"Comma-separated list of activation severities, i.e the severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Asc string `url:"asc,omitempty"` // Description:"Ascending sort",ExampleValue:""
AvailableSince string `url:"available_since,omitempty"` // Description:"Filters rules added since date. Format is yyyy-MM-dd",ExampleValue:"2014-06-22"
Facets string `url:"facets,omitempty"` // Description:"Comma-separated list of the facets to be computed. No facet is computed by default.",ExampleValue:"languages,repositories"
Inheritance string `url:"inheritance,omitempty"` // Description:"Comma-separated list of values of inheritance for a rule within a quality profile. Used only if the parameter 'activation' is set.",ExampleValue:"INHERITED,OVERRIDES"
IsTemplate string `url:"is_template,omitempty"` // Description:"Filter template rules",ExampleValue:""
Languages string `url:"languages,omitempty"` // Description:"Comma-separated list of languages",ExampleValue:"java,js"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"UTF-8 search query",ExampleValue:"xpath"
Qprofile string `url:"qprofile,omitempty"` // Description:"Quality profile key to filter on. Used only if the parameter 'activation' is set.",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
Repositories string `url:"repositories,omitempty"` // Description:"Comma-separated list of repositories",ExampleValue:"checkstyle,findbugs"
RuleKey string `url:"rule_key,omitempty"` // Description:"Key of rule to search for",ExampleValue:"squid:S001"
S string `url:"s,omitempty"` // Description:"Sort field",ExampleValue:"name"
Severities string `url:"severities,omitempty"` // Description:"Comma-separated list of default severities. Not the same than severity of rules in Quality profiles.",ExampleValue:"CRITICAL,BLOCKER"
Statuses string `url:"statuses,omitempty"` // Description:"Comma-separated list of status codes",ExampleValue:"READY"
Tags string `url:"tags,omitempty"` // Description:"Comma-separated list of tags. Returned rules match any of the tags (OR operator)",ExampleValue:"security,java8"
TemplateKey string `url:"template_key,omitempty"` // Description:"Key of the template rule to filter on. Used to search for the custom rules based on this template.",ExampleValue:"java:S001"
Types string `url:"types,omitempty"` // Description:"Comma-separated list of types. Returned rules match any of the tags (OR operator)",ExampleValue:"BUG"
}
// Search Search for a collection of relevant rules matching a specified query.<br/>Since 5.5, following fields in the response have been deprecated :<ul><li>"effortToFixDescription" becomes "gapDescription"</li><li>"debtRemFnCoeff" becomes "remFnGapMultiplier"</li><li>"defaultDebtRemFnCoeff" becomes "defaultRemFnGapMultiplier"</li><li>"debtRemFnOffset" becomes "remFnBaseEffort"</li><li>"defaultDebtRemFnOffset" becomes "defaultRemFnBaseEffort"</li><li>"debtOverloaded" becomes "remFnOverloaded"</li></ul>
func (s *RulesService) Search(opt *RulesSearchOption) (v *RulesSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "rules/search", opt)
if err != nil {
return
}
v = new(RulesSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type RulesShowOption struct {
Actives string `url:"actives,omitempty"` // Description:"Show rule's activations for all profiles ("active rules")",ExampleValue:""
Key string `url:"key,omitempty"` // Description:"Rule key",ExampleValue:"javascript:EmptyBlock"
}
// Show Get detailed information about a rule<br>Since 5.5, following fields in the response have been deprecated :<ul><li>"effortToFixDescription" becomes "gapDescription"</li><li>"debtRemFnCoeff" becomes "remFnGapMultiplier"</li><li>"defaultDebtRemFnCoeff" becomes "defaultRemFnGapMultiplier"</li><li>"debtRemFnOffset" becomes "remFnBaseEffort"</li><li>"defaultDebtRemFnOffset" becomes "defaultRemFnBaseEffort"</li><li>"debtOverloaded" becomes "remFnOverloaded"</li></ul>In 7.1, the field 'scope' has been added.
func (s *RulesService) Show(opt *RulesShowOption) (v *RulesShowObject, resp *http.Response, err error) {
err = s.ValidateShowOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "rules/show", opt)
if err != nil {
return
}
v = new(RulesShowObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type RulesTagsOption struct {
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 100",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to tags that contain the supplied string.",ExampleValue:"misra"
}
// Tags List rule tags
func (s *RulesService) Tags(opt *RulesTagsOption) (v *IssuesTagsObject, resp *http.Response, err error) {
err = s.ValidateTagsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "rules/tags", opt)
if err != nil {
return
}
v = new(IssuesTagsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type RulesUpdateOption struct {
DebtRemediationFnOffset string `url:"debt_remediation_fn_offset,omitempty"` // Description:"",ExampleValue:""
DebtRemediationFnType string `url:"debt_remediation_fn_type,omitempty"` // Description:"",ExampleValue:""
DebtRemediationFyCoeff string `url:"debt_remediation_fy_coeff,omitempty"` // Description:"",ExampleValue:""
DebtSubCharacteristic string `url:"debt_sub_characteristic,omitempty"` // Description:"Debt characteristics are no more supported. This parameter is ignored.",ExampleValue:""
Key string `url:"key,omitempty"` // Description:"Key of the rule to update",ExampleValue:"javascript:NullCheck"
MarkdownDescription string `url:"markdown_description,omitempty"` // Description:"Rule description (mandatory for custom rule and manual rule)",ExampleValue:"Description of my custom rule"
MarkdownNote string `url:"markdown_note,omitempty"` // Description:"Optional note in markdown format. Use empty value to remove current note. Note is not changedif the parameter is not set.",ExampleValue:"my *note*"
Name string `url:"name,omitempty"` // Description:"Rule name (mandatory for custom rule)",ExampleValue:"My custom rule"
Params string `url:"params,omitempty"` // Description:"Parameters as semi-colon list of <key>=<value>, for example 'params=key1=v1;key2=v2' (Only when updating a custom rule)",ExampleValue:""
RemediationFnBaseEffort string `url:"remediation_fn_base_effort,omitempty"` // Description:"Base effort of the remediation function of the rule",ExampleValue:"1d"
RemediationFnType string `url:"remediation_fn_type,omitempty"` // Description:"Type of the remediation function of the rule",ExampleValue:""
RemediationFyGapMultiplier string `url:"remediation_fy_gap_multiplier,omitempty"` // Description:"Gap multiplier of the remediation function of the rule",ExampleValue:"3min"
Severity string `url:"severity,omitempty"` // Description:"Rule severity (Only when updating a custom rule)",ExampleValue:""
Status string `url:"status,omitempty"` // Description:"Rule status (Only when updating a custom rule)",ExampleValue:""
Tags string `url:"tags,omitempty"` // Description:"Optional comma-separated list of tags to set. Use blank value to remove current tags. Tags are not changed if the parameter is not set.",ExampleValue:"java8,security"
}
// Update Update an existing rule.<br>Requires the 'Administer Quality Profiles' permission
func (s *RulesService) Update(opt *RulesUpdateOption) (v *RuleUpdateObject, resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "rules/update", opt)
if err != nil {
return
}
v = new(RuleUpdateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}

View File

@@ -0,0 +1,22 @@
//
package sonargo
import "net/http"
type ServerService struct {
client *Client
}
// Version Version of SonarQube in plain text
func (s *ServerService) Version() (v *string, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "server/version", nil)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,140 @@
// Manage settings.
package sonargo
import "net/http"
type SettingsService struct {
client *Client
}
type SettingsListDefinitionsObject struct {
Definitions []*Definition `json:"definitions,omitempty"`
}
type Definition struct {
Category string `json:"category,omitempty"`
DefaultValue string `json:"defaultValue,omitempty"`
DeprecatedKey string `json:"deprecatedKey,omitempty"`
Description string `json:"description,omitempty"`
Fields []*Field `json:"fields,omitempty"`
Key string `json:"key,omitempty"`
MultiValues bool `json:"multiValues,omitempty"`
Name string `json:"name,omitempty"`
Options []string `json:"options,omitempty"`
SubCategory string `json:"subCategory,omitempty"`
Type string `json:"type,omitempty"`
}
type Field struct {
Description string `json:"description,omitempty"`
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
Options []string `json:"options,omitempty"`
Type string `json:"type,omitempty"`
}
type SettingsValuesObject struct {
Settings []*Setting `json:"settings,omitempty"`
}
type FieldValue struct {
Boolean string `json:"boolean,omitempty"`
Text string `json:"text,omitempty"`
}
type Setting struct {
Key string `json:"key,omitempty"`
Value string `json:"value,omitempty"`
Inherited bool `json:"inherited,omitempty"`
Values []string `json:"values,omitempty"`
FieldValues []*FieldValue `json:"fieldValues,omitempty"`
}
type SettingsListDefinitionsOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
}
// ListDefinitions List settings definitions.<br>Requires 'Browse' permission when a component is specified<br/>
func (s *SettingsService) ListDefinitions(opt *SettingsListDefinitionsOption) (v *SettingsListDefinitionsObject, resp *http.Response, err error) {
err = s.ValidateListDefinitionsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "settings/list_definitions", opt)
if err != nil {
return
}
v = new(SettingsListDefinitionsObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type SettingsResetOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
Keys string `url:"keys,omitempty"` // Description:"Comma-separated list of keys",ExampleValue:"sonar.links.scm,sonar.debt.hoursInDay"
}
// Reset Remove a setting value.<br>The settings defined in config/sonar.properties are read-only and can't be changed.<br/>Requires one of the following permissions: <ul><li>'Administer System'</li><li>'Administer' rights on the specified component</li></ul>
func (s *SettingsService) Reset(opt *SettingsResetOption) (resp *http.Response, err error) {
err = s.ValidateResetOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "settings/reset", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type SettingsSetOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
FieldValues string `url:"fieldValues,omitempty"` // Description:"Setting field values. To set several values, the parameter must be called once for each value.",ExampleValue:"fieldValues={"firstField":"first value", "secondField":"second value", "thirdField":"third value"}"
Key string `url:"key,omitempty"` // Description:"Setting key",ExampleValue:"sonar.links.scm"
Value string `url:"value,omitempty"` // Description:"Setting value. To reset a value, please use the reset web service.",ExampleValue:"git@github.com:SonarSource/sonarqube.git"
Values []string `url:"values,omitempty"` // Description:"Setting multi value. To set several values, the parameter must be called once for each value.",ExampleValue:"values=firstValue&values=secondValue&values=thirdValue"
}
// Set Update a setting value.<br>Either 'value' or 'values' must be provided.<br> The settings defined in config/sonar.properties are read-only and can't be changed.<br/>Requires one of the following permissions: <ul><li>'Administer System'</li><li>'Administer' rights on the specified component</li></ul>
func (s *SettingsService) Set(opt *SettingsSetOption) (resp *http.Response, err error) {
err = s.ValidateSetOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "settings/set", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type SettingsValuesOption struct {
Component string `url:"component,omitempty"` // Description:"Component key",ExampleValue:"my_project"
Keys string `url:"keys,omitempty"` // Description:"List of setting keys",ExampleValue:"sonar.test.inclusions,sonar.dbcleaner.cleanDirectory"
}
// Values List settings values.<br>If no value has been set for a setting, then the default value is returned.<br>The settings from conf/sonar.properties are excluded from results.<br>Requires 'Browse' or 'Execute Analysis' permission when a component is specified<br/>
func (s *SettingsService) Values(opt *SettingsValuesOption) (v *SettingsValuesObject, resp *http.Response, err error) {
err = s.ValidateValuesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "settings/values", opt)
if err != nil {
return
}
v = new(SettingsValuesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

110
vendor/github.com/kubesphere/sonargo/sonar/sonarqube.go generated vendored Normal file
View File

@@ -0,0 +1,110 @@
package sonargo
import (
"net/http"
"net/url"
"github.com/google/go-querystring/query"
)
const (
defaultBaseURL = "http://sonarqube.kubesphere.com/api/"
userAgent = "devops server"
)
type authType int
const (
basicAuth authType = iota
oAuthToken
privateToken
)
const (
QualifierSubProject = "BRC"
QualifierDirectory = "DIR"
QualifierFile = "FIL"
QualifierProject = "TRK"
QualifierTestFile = "UTS"
)
func (c *Client) BaseURL() *url.URL {
u := *c.baseURL
return &u
}
// SetBaseURL sets the base URL for API requests to a custom endpoint. urlStr
// should always be specified with a trailing slash.
func (c *Client) SetBaseURL(urlStr string) error {
if u, err := SetBaseURLUtil(urlStr); err != nil {
return err
} else {
c.baseURL = u
}
return nil
}
// NewRequest creates an API request. A relative URL path can be provided in
// urlStr, in which case it is resolved relative to the base URL of the Client.
// Relative URL paths should always be specified without a preceding slash. If
// specified, the value pointed to by body is JSON encoded and included as the
// request body.
func (c *Client) NewRequest(method, path string, opt interface{}) (*http.Request, error) {
u := *c.baseURL
// Set the encoded opaque data
u.Opaque = c.baseURL.Path + path
if opt != nil {
q, err := query.Values(opt)
if err != nil {
return nil, err
}
u.RawQuery = q.Encode()
}
req := &http.Request{
Method: method,
URL: &u,
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
Header: make(http.Header),
Host: u.Host,
}
if method == "POST" || method == "PUT" {
// SonarQube use RawQuery even method is POST
// bodyBytes, err := json.Marshal(opt)
// if err != nil {
// return nil, err
// }
// bodyReader := bytes.NewReader(bodyBytes)
// u.RawQuery = ""
// req.Body = ioutil.NopCloser(bodyReader)
// req.ContentLength = int64(bodyReader.Len())
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("Accept", "application/json")
req.SetBasicAuth(c.username, c.password)
req.Header.Set("User-Agent", userAgent)
return req, nil
}
// Do sends an API request and returns the API response. The API response is
// JSON decoded and stored in the value pointed to by v, or returned as an
// error if an API error has occurred. If v implements the io.Writer
// interface, the raw response body will be written to v, without attempting to
// first decode it.
func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) {
return Do(c.httpClient, req, v)
}
//Paging is used in many apis
type Paging struct {
PageIndex int `json:"pageIndex,omitempty"`
PageSize int `json:"pageSize,omitempty"`
Total int `json:"total,omitempty"`
}

View File

@@ -0,0 +1,87 @@
// Get details on source files. See also api/tests.
package sonargo
import "net/http"
type SourcesService struct {
client *Client
}
type SourcesSCMObject struct {
SCM [][]interface{} `json:"scm,omitempty"`
}
type SourcesShowObject struct {
Sources [][]interface{} `json:"sources,omitempty"`
}
type SourcesRawOption struct {
Key string `url:"key,omitempty"` // Description:"File key",ExampleValue:"my_project:src/foo/Bar.php"
}
// Raw Get source code as raw text. Require 'See Source Code' permission on file
func (s *SourcesService) Raw(opt *SourcesRawOption) (v *string, resp *http.Response, err error) {
err = s.ValidateRawOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "sources/raw", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type SourcesSCMOption struct {
CommitsByLine string `url:"commits_by_line,omitempty"` // Description:"Group lines by SCM commit if value is false, else display commits for each line, even if two consecutive lines relate to the same commit.",ExampleValue:""
From string `url:"from,omitempty"` // Description:"First line to return. Starts at 1",ExampleValue:"10"
Key string `url:"key,omitempty"` // Description:"File key",ExampleValue:"my_project:/src/foo/Bar.php"
To string `url:"to,omitempty"` // Description:"Last line to return (inclusive)",ExampleValue:"20"
}
// SCM Get SCM information of source files. Require See Source Code permission on file's project<br/>Each element of the result array is composed of:<ol><li>Line number</li><li>Author of the commit</li><li>Datetime of the commit (before 5.2 it was only the Date)</li><li>Revision of the commit (added in 5.2)</li></ol>
func (s *SourcesService) SCM(opt *SourcesSCMOption) (v *SourcesSCMObject, resp *http.Response, err error) {
err = s.ValidateSCMOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "sources/scm", opt)
if err != nil {
return
}
v = new(SourcesSCMObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type SourcesShowOption struct {
From string `url:"from,omitempty"` // Description:"First line to return. Starts at 1",ExampleValue:"10"
Key string `url:"key,omitempty"` // Description:"File key",ExampleValue:"my_project:/src/foo/Bar.php"
To string `url:"to,omitempty"` // Description:"Last line to return (inclusive)",ExampleValue:"20"
}
// Show Get source code. Require See Source Code permission on file's project<br/>Each element of the result array is composed of:<ol><li>Line number</li><li>Content of the line</li></ol>
func (s *SourcesService) Show(opt *SourcesShowOption) (v *SourcesShowObject, resp *http.Response, err error) {
err = s.ValidateShowOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "sources/show", opt)
if err != nil {
return
}
v = new(SourcesShowObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,226 @@
// Get system details, and perform some management actions, such as restarting, and initiating a database migration (as part of a system upgrade).
package sonargo
import "net/http"
type SystemService struct {
client *Client
}
type LogLevel string
const (
LogLevelInfo LogLevel = "INFO"
LogLevelDebug LogLevel = "DEBUG"
LogLevelTrace LogLevel = "TRACE"
)
type Cause struct {
Message string `json:"message,omitempty"`
StartedAt string `json:"startedAt,omitempty"`
State string `json:"state,omitempty"`
}
type SystemHealthObject struct {
Causes []*Cause `json:"causes,omitempty"`
Health string `json:"health,omitempty"`
Nodes []*Node `json:"nodes,omitempty"`
}
type Node struct {
Causes []*Cause `json:"causes,omitempty"`
Health string `json:"health,omitempty"`
Host string `json:"host,omitempty"`
Name string `json:"name,omitempty"`
Port int64 `json:"port,omitempty"`
StartedAt string `json:"startedAt,omitempty"`
Type string `json:"type,omitempty"`
}
type SystemStatusObject struct {
ID string `json:"id,omitempty"`
Status string `json:"status,omitempty"`
Version string `json:"version,omitempty"`
}
type SystemUpgradesObject struct {
UpdateCenterRefresh string `json:"updateCenterRefresh,omitempty"`
Upgrades []*Upgrade `json:"upgrades,omitempty"`
}
type Incompatible struct {
Category string `json:"category,omitempty"`
Description string `json:"description,omitempty"`
EditionBundled bool `json:"editionBundled,omitempty"`
Key string `json:"key,omitempty"`
License string `json:"license,omitempty"`
Name string `json:"name,omitempty"`
OrganizationName string `json:"organizationName,omitempty"`
OrganizationURL string `json:"organizationUrl,omitempty"`
}
type UpgradePlugins struct {
Incompatible []*Incompatible `json:"incompatible,omitempty"`
RequireUpdate []*RequireUpdate `json:"requireUpdate,omitempty"`
}
type RequireUpdate struct {
Category string `json:"category,omitempty"`
Description string `json:"description,omitempty"`
EditionBundled bool `json:"editionBundled,omitempty"`
Key string `json:"key,omitempty"`
License string `json:"license,omitempty"`
Name string `json:"name,omitempty"`
OrganizationName string `json:"organizationName,omitempty"`
OrganizationURL string `json:"organizationUrl,omitempty"`
TermsAndConditionsURL string `json:"termsAndConditionsUrl,omitempty"`
Version string `json:"version,omitempty"`
}
type Upgrade struct {
ChangeLogURL string `json:"changeLogUrl,omitempty"`
Description string `json:"description,omitempty"`
DownloadURL string `json:"downloadUrl,omitempty"`
Plugins *UpgradePlugins `json:"plugins,omitempty"`
ReleaseDate string `json:"releaseDate,omitempty"`
Version string `json:"version,omitempty"`
}
type SystemChangeLogLevelOption struct {
Level LogLevel `url:"level,omitempty"` // Description:"The new level. Be cautious: DEBUG, and even more TRACE, may have performance impacts.",ExampleValue:""
}
// ChangeLogLevel Temporarily changes level of logs. New level is not persistent and is lost when restarting server. Requires system administration permission.
func (s *SystemService) ChangeLogLevel(opt *SystemChangeLogLevelOption) (resp *http.Response, err error) {
err = s.ValidateChangeLogLevelOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "system/change_log_level", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
// DbMigrationStatus Display the database migration status of SonarQube.<br/>State values are:<ul><li>NO_MIGRATION: DB is up to date with current version of SonarQube.</li><li>NOT_SUPPORTED: Migration is not supported on embedded databases.</li><li>MIGRATION_RUNNING: DB migration is under go.</li><li>MIGRATION_SUCCEEDED: DB migration has run and has been successful.</li><li>MIGRATION_FAILED: DB migration has run and failed. SonarQube must be restarted in order to retry a DB migration (optionally after DB has been restored from backup).</li><li>MIGRATION_REQUIRED: DB migration is required.</li></ul>
func (s *SystemService) DbMigrationStatus() (v *Cause, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "system/db_migration_status", nil)
if err != nil {
return
}
v = new(Cause)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Health Provide health status of SonarQube.<p>Require 'Administer System' permission or authentication with passcode</p><p> <ul> <li>GREEN: SonarQube is fully operational</li> <li>YELLOW: SonarQube is usable, but it needs attention in order to be fully operational</li> <li>RED: SonarQube is not operational</li> </ul></p>
func (s *SystemService) Health() (v *SystemHealthObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "system/health", nil)
if err != nil {
return
}
v = new(SystemHealthObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type SystemLogsOption struct {
Process string `url:"process,omitempty"` // Description:"Process to get logs from",ExampleValue:""
}
// Logs Get system logs in plain-text format. Requires system administration permission.
func (s *SystemService) Logs(opt *SystemLogsOption) (v *string, resp *http.Response, err error) {
err = s.ValidateLogsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "system/logs", opt)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// MigrateDb Migrate the database to match the current version of SonarQube.<br/>Sending a POST request to this URL starts the DB migration. It is strongly advised to <strong>make a database backup</strong> before invoking this WS.<br/>State values are:<ul><li>NO_MIGRATION: DB is up to date with current version of SonarQube.</li><li>NOT_SUPPORTED: Migration is not supported on embedded databases.</li><li>MIGRATION_RUNNING: DB migration is under go.</li><li>MIGRATION_SUCCEEDED: DB migration has run and has been successful.</li><li>MIGRATION_FAILED: DB migration has run and failed. SonarQube must be restarted in order to retry a DB migration (optionally after DB has been restored from backup).</li><li>MIGRATION_REQUIRED: DB migration is required.</li></ul>
func (s *SystemService) MigrateDb() (v *Cause, resp *http.Response, err error) {
req, err := s.client.NewRequest("POST", "system/migrate_db", nil)
if err != nil {
return
}
v = new(Cause)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Ping Answers "pong" as plain-text
func (s *SystemService) Ping() (v *string, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "system/ping", nil)
if err != nil {
return
}
v = new(string)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Restart Restart server. Require 'Administer System' permission. Perform a full restart of the Web, Search and Compute Engine Servers processes.
func (s *SystemService) Restart() (resp *http.Response, err error) {
req, err := s.client.NewRequest("POST", "system/restart", nil)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
// Status Get state information about SonarQube.<p>status: the running status <ul> <li>STARTING: SonarQube Web Server is up and serving some Web Services (eg. api/system/status) but initialization is still ongoing</li> <li>UP: SonarQube instance is up and running</li> <li>DOWN: SonarQube instance is up but not running because migration has failed (refer to WS /api/system/migrate_db for details) or some other reason (check logs).</li> <li>RESTARTING: SonarQube instance is still up but a restart has been requested (refer to WS /api/system/restart for details).</li> <li>DB_MIGRATION_NEEDED: database migration is required. DB migration can be started using WS /api/system/migrate_db.</li> <li>DB_MIGRATION_RUNNING: DB migration is running (refer to WS /api/system/migrate_db for details)</li> </ul></p>
func (s *SystemService) Status() (v *SystemStatusObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "system/status", nil)
if err != nil {
return
}
v = new(SystemStatusObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
// Upgrades Lists available upgrades for the SonarQube instance (if any) and for each one, lists incompatible plugins and plugins requiring upgrade.<br/>Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response.
func (s *SystemService) Upgrades() (v *SystemUpgradesObject, resp *http.Response, err error) {
req, err := s.client.NewRequest("GET", "system/upgrades", nil)
if err != nil {
return
}
v = new(SystemUpgradesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,201 @@
// Manage user groups.
package sonargo
import "net/http"
type UserGroupsService struct {
client *Client
}
type UserGroupsCreateObject struct {
Group *Group `json:"group,omitempty"`
}
type Group struct {
Default bool `json:"default,omitempty"`
Description string `json:"description,omitempty"`
ID int `json:"id,omitempty"`
MembersCount int64 `json:"membersCount,omitempty"`
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Selected bool `json:"selected,omitempty"`
}
type UserGroupsSearchObject struct {
Groups []*Group `json:"groups,omitempty"`
Paging *Paging `json:"paging,omitempty"`
}
type UserGroupsUsersObject struct {
Users []*User `json:"users,omitempty"`
Total int `json:"total,omitempty"`
P int `json:"p,omitempty"`
Ps int `json:"ps,omitempty"`
}
type UserGroupsAddUserOption struct {
Id int `url:"id,omitempty"` // Description:"Group id",ExampleValue:"42"
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
Name string `url:"name,omitempty"` // Description:"Group name",ExampleValue:"sonar-administrators"
}
// AddUser Add a user to a group.<br />'id' or 'name' must be provided.<br />Requires the following permission: 'Administer System'.
func (s *UserGroupsService) AddUser(opt *UserGroupsAddUserOption) (resp *http.Response, err error) {
err = s.ValidateAddUserOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_groups/add_user", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type UserGroupsCreateOption struct {
Description string `url:"description,omitempty"` // Description:"Description for the new group. A group description cannot be larger than 200 characters.",ExampleValue:"Default group for new users"
Name string `url:"name,omitempty"` // Description:"Name for the new group. A group name cannot be larger than 255 characters and must be unique. The value 'anyone' (whatever the case) is reserved and cannot be used.",ExampleValue:"sonar-users"
}
// Create Create a group.<br>Requires the following permission: 'Administer System'.
func (s *UserGroupsService) Create(opt *UserGroupsCreateOption) (v *UserGroupsCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_groups/create", opt)
if err != nil {
return
}
v = new(UserGroupsCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UserGroupsDeleteOption struct {
Id int `url:"id,omitempty"` // Description:"Group id",ExampleValue:"42"
Name string `url:"name,omitempty"` // Description:"Group name",ExampleValue:"sonar-administrators"
}
// Delete Delete a group. The default groups cannot be deleted.<br/>'id' or 'name' must be provided.<br />Requires the following permission: 'Administer System'.
func (s *UserGroupsService) Delete(opt *UserGroupsDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_groups/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type UserGroupsRemoveUserOption struct {
Id int `url:"id,omitempty"` // Description:"Group id",ExampleValue:"42"
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
Name string `url:"name,omitempty"` // Description:"Group name",ExampleValue:"sonar-administrators"
}
// RemoveUser Remove a user from a group.<br />'id' or 'name' must be provided.<br>Requires the following permission: 'Administer System'.
func (s *UserGroupsService) RemoveUser(opt *UserGroupsRemoveUserOption) (resp *http.Response, err error) {
err = s.ValidateRemoveUserOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_groups/remove_user", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type UserGroupsSearchOption struct {
F string `url:"f,omitempty"` // Description:"Comma-separated list of the fields to be returned in response. All the fields are returned by default.",ExampleValue:""
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to names that contain the supplied string.",ExampleValue:"sonar-users"
}
// Search Search for user groups.<br>Requires the following permission: 'Administer System'.
func (s *UserGroupsService) Search(opt *UserGroupsSearchOption) (v *UserGroupsSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "user_groups/search", opt)
if err != nil {
return
}
v = new(UserGroupsSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UserGroupsUpdateOption struct {
Description string `url:"description,omitempty"` // Description:"New optional description for the group. A group description cannot be larger than 200 characters. If value is not defined, then description is not changed.",ExampleValue:"Default group for new users"
Id int `url:"id,omitempty"` // Description:"Identifier of the group.",ExampleValue:"42"
Name string `url:"name,omitempty"` // Description:"New optional name for the group. A group name cannot be larger than 255 characters and must be unique. Value 'anyone' (whatever the case) is reserved and cannot be used. If value is empty or not defined, then name is not changed.",ExampleValue:"my-group"
}
// Update Update a group.<br>Requires the following permission: 'Administer System'.
func (s *UserGroupsService) Update(opt *UserGroupsUpdateOption) (v *UserGroupsCreateObject, resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_groups/update", opt)
if err != nil {
return
}
v = new(UserGroupsCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return
}
return
}
type UserGroupsUsersOption struct {
Id int `url:"id,omitempty"` // Description:"Group id",ExampleValue:"42"
Name string `url:"name,omitempty"` // Description:"Group name",ExampleValue:"sonar-administrators"
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0.",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to names or logins that contain the supplied string.",ExampleValue:"freddy"
Selected string `url:"selected,omitempty"` // Description:"Depending on the value, show only selected items (selected=selected), deselected items (selected=deselected), or all items with their selection status (selected=all).",ExampleValue:""
}
// Users Search for users with membership information with respect to a group.<br>Requires the following permission: 'Administer System'.
func (s *UserGroupsService) Users(opt *UserGroupsUsersOption) (v *UserGroupsUsersObject, resp *http.Response, err error) {
err = s.ValidateUsersOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "user_groups/users", opt)
if err != nil {
return
}
v = new(UserGroupsUsersObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,92 @@
// List, create, and delete a user's access tokens.
package sonargo
import "net/http"
type UserTokensService struct {
client *Client
}
type UserTokensGenerateObject struct {
CreatedAt string `json:"createdAt,omitempty"`
Login string `json:"login,omitempty"`
Name string `json:"name,omitempty"`
Token string `json:"token,omitempty"`
}
type UserTokensSearchObject struct {
Login string `json:"login,omitempty"`
UserTokens []*UserToken `json:"userTokens,omitempty"`
}
type UserToken struct {
CreatedAt string `json:"createdAt,omitempty"`
Name string `json:"name,omitempty"`
}
type UserTokensGenerateOption struct {
Login string `url:"login,omitempty"` // Description:"User login. If not set, the token is generated for the authenticated user.",ExampleValue:"g.hopper"
Name string `url:"name,omitempty"` // Description:"Token name",ExampleValue:"Project scan on Travis"
}
// Generate Generate a user access token. <br />Please keep your tokens secret. They enable to authenticate and analyze projects.<br />If the login is set, it requires administration permissions. Otherwise, a token is generated for the authenticated user.
func (s *UserTokensService) Generate(opt *UserTokensGenerateOption) (v *UserTokensGenerateObject, resp *http.Response, err error) {
err = s.ValidateGenerateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_tokens/generate", opt)
if err != nil {
return
}
v = new(UserTokensGenerateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UserTokensRevokeOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
Name string `url:"name,omitempty"` // Description:"Token name",ExampleValue:"Project scan on Travis"
}
// Revoke Revoke a user access token. <br/>If the login is set, it requires administration permissions. Otherwise, a token is generated for the authenticated user.
func (s *UserTokensService) Revoke(opt *UserTokensRevokeOption) (resp *http.Response, err error) {
err = s.ValidateRevokeOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "user_tokens/revoke", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type UserTokensSearchOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"g.hopper"
}
// Search List the access tokens of a user.<br>The login must exist and active.<br>If the login is set, it requires administration permissions. Otherwise, a token is generated for the authenticated user.
func (s *UserTokensService) Search(opt *UserTokensSearchOption) (v *UserTokensSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "user_tokens/search", opt)
if err != nil {
return
}
v = new(UserTokensSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,180 @@
// Manage users.
package sonargo
import "net/http"
type UsersService struct {
client *Client
}
type UsersCreateObject struct {
User *User `json:"user,omitempty"`
}
type User struct {
Active bool `json:"active,omitempty"`
Email string `json:"email,omitempty"`
Local bool `json:"local,omitempty"`
Login string `json:"login,omitempty"`
Name string `json:"name,omitempty"`
ScmAccounts []string `json:"scmAccounts,omitempty"`
Selected bool `json:"selected,omitempty"`
TokensCount int `json:"tokensCount,omitempty"`
ExternalIdentity string `json:"externalIdentity,omitempty"`
ExternalProvider string `json:"externalProvider,omitempty"`
Groups []string `json:"groups,omitempty"`
Avatar string `json:"avatar,omitempty"`
}
type UsersChangePasswordOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"myuser"
Password string `url:"password,omitempty"` // Description:"New password",ExampleValue:"mypassword"
PreviousPassword string `url:"previousPassword,omitempty"` // Description:"Previous password. Required when changing one's own password.",ExampleValue:"oldpassword"
}
// ChangePassword Update a user's password. Authenticated users can change their own password, provided that the account is not linked to an external authentication system. Administer System permission is required to change another user's password.
func (s *UsersService) ChangePassword(opt *UsersChangePasswordOption) (resp *http.Response, err error) {
err = s.ValidateChangePasswordOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "users/change_password", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type UsersCreateOption struct {
Email string `url:"email,omitempty"` // Description:"User email",ExampleValue:"myname@email.com"
Local string `url:"local,omitempty"` // Description:"Specify if the user should be authenticated from SonarQube server or from an external authentication system. Password should not be set when local is set to false.",ExampleValue:""
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"myuser"
Name string `url:"name,omitempty"` // Description:"User name",ExampleValue:"My Name"
Password string `url:"password,omitempty"` // Description:"User password. Only mandatory when creating local user, otherwise it should not be set",ExampleValue:"mypassword"
ScmAccount string `url:"scmAccount,omitempty"` // Description:"List of SCM accounts. To set several values, the parameter must be called once for each value.",ExampleValue:"scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue"
}
// Create Create a user.<br/>If a deactivated user account exists with the given login, it will be reactivated.<br/>Requires Administer System permission
func (s *UsersService) Create(opt *UsersCreateOption) (v *UsersCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "users/create", opt)
if err != nil {
return
}
v = new(UsersCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UsersDeactivateOption struct {
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"myuser"
}
// Deactivate Deactivate a user. Requires Administer System permission
func (s *UsersService) Deactivate(opt *UsersDeactivateOption) (v *UsersCreateObject, resp *http.Response, err error) {
err = s.ValidateDeactivateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "users/deactivate", opt)
if err != nil {
return
}
v = new(UsersCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UsersGroupsOption struct {
Login string `url:"login,omitempty"` // Description:"A user login",ExampleValue:"admin"
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0.",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Limit search to group names that contain the supplied string.",ExampleValue:"users"
Selected string `url:"selected,omitempty"` // Description:"Depending on the value, show only selected items (selected=selected), deselected items (selected=deselected), or all items with their selection status (selected=all).",ExampleValue:""
}
// Groups Lists the groups a user belongs to. <br/>Requires Administer System permission.
func (s *UsersService) Groups(opt *UsersGroupsOption) (v *UserGroupsSearchObject, resp *http.Response, err error) {
err = s.ValidateGroupsOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "users/groups", opt)
if err != nil {
return
}
v = new(UserGroupsSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UsersSearchOption struct {
F string `url:"f,omitempty"` // Description:"Comma-separated list of the fields to be returned in response. All the fields are returned by default.",ExampleValue:""
P int `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps int `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less or equal than 500",ExampleValue:"20"
Q string `url:"q,omitempty"` // Description:"Filter on login, name and email",ExampleValue:""
}
type UsersSearchObject struct {
Paging *Paging `json:"paging,omitempty"`
Users []*User `json:"users,omitempty"`
}
// Search Get a list of active users. <br/>Administer System permission is required to show the 'groups' field.<br/>When accessed anonymously, only logins and names are returned.
func (s *UsersService) Search(opt *UsersSearchOption) (v *UsersSearchObject, resp *http.Response, err error) {
err = s.ValidateSearchOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "users/search", opt)
if err != nil {
return
}
v = new(UsersSearchObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type UsersUpdateOption struct {
Email string `url:"email,omitempty"` // Description:"User email",ExampleValue:"myname@email.com"
Login string `url:"login,omitempty"` // Description:"User login",ExampleValue:"myuser"
Name string `url:"name,omitempty"` // Description:"User name",ExampleValue:"My Name"
ScmAccount string `url:"scmAccount,omitempty"` // Description:"SCM accounts. To set several values, the parameter must be called once for each value.",ExampleValue:"scmAccount=firstValue&scmAccount=secondValue&scmAccount=thirdValue"
}
// Update Update a user. If a deactivated user account exists with the given login, it will be reactivated. Requires Administer System permission
func (s *UsersService) Update(opt *UsersUpdateOption) (v *UsersCreateObject, resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "users/update", opt)
if err != nil {
return
}
v = new(UsersCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}

View File

@@ -0,0 +1,458 @@
// [TODO] Code generated by "github.com/magicsong/generate-go-for-sonarqube", you should edit some validation logic here
package sonargo
func (s *CeService) ValidateActivityOpt(opt *CeActivityOption) error {
return nil
}
func (s *CeService) ValidateComponentOpt(opt *CeComponentOption) error {
return nil
}
func (s *CeService) ValidateTaskOpt(opt *CeTaskOption) error {
return nil
}
func (s *ComponentsService) ValidateSearchOpt(opt *ComponentsSearchOption) error {
return nil
}
func (s *ComponentsService) ValidateShowOpt(opt *ComponentsShowOption) error {
return nil
}
func (s *ComponentsService) ValidateTreeOpt(opt *ComponentsTreeOption) error {
return nil
}
func (s *DuplicationsService) ValidateShowOpt(opt *DuplicationsShowOption) error {
return nil
}
func (s *FavoritesService) ValidateAddOpt(opt *FavoritesAddOption) error {
return nil
}
func (s *FavoritesService) ValidateRemoveOpt(opt *FavoritesRemoveOption) error {
return nil
}
func (s *FavoritesService) ValidateSearchOpt(opt *FavoritesSearchOption) error {
return nil
}
func (s *IssuesService) ValidateAddCommentOpt(opt *IssuesAddCommentOption) error {
return nil
}
func (s *IssuesService) ValidateAssignOpt(opt *IssuesAssignOption) error {
return nil
}
func (s *IssuesService) ValidateAuthorsOpt(opt *IssuesAuthorsOption) error {
return nil
}
func (s *IssuesService) ValidateBulkChangeOpt(opt *IssuesBulkChangeOption) error {
return nil
}
func (s *IssuesService) ValidateChangelogOpt(opt *IssuesChangelogOption) error {
return nil
}
func (s *IssuesService) ValidateDeleteCommentOpt(opt *IssuesDeleteCommentOption) error {
return nil
}
func (s *IssuesService) ValidateDoTransitionOpt(opt *IssuesDoTransitionOption) error {
return nil
}
func (s *IssuesService) ValidateEditCommentOpt(opt *IssuesEditCommentOption) error {
return nil
}
func (s *IssuesService) ValidateSearchOpt(opt *IssuesSearchOption) error {
return nil
}
func (s *IssuesService) ValidateSetSeverityOpt(opt *IssuesSetSeverityOption) error {
return nil
}
func (s *IssuesService) ValidateSetTagsOpt(opt *IssuesSetTagsOption) error {
return nil
}
func (s *IssuesService) ValidateSetTypeOpt(opt *IssuesSetTypeOption) error {
return nil
}
func (s *IssuesService) ValidateTagsOpt(opt *IssuesTagsOption) error {
return nil
}
func (s *LanguagesService) ValidateListOpt(opt *LanguagesListOption) error {
return nil
}
func (s *MeasuresService) ValidateComponentOpt(opt *MeasuresComponentOption) error {
return nil
}
func (s *MeasuresService) ValidateComponentTreeOpt(opt *MeasuresComponentTreeOption) error {
return nil
}
func (s *MeasuresService) ValidateSearchHistoryOpt(opt *MeasuresSearchHistoryOption) error {
return nil
}
func (s *MetricsService) ValidateCreateOpt(opt *MetricsCreateOption) error {
return nil
}
func (s *MetricsService) ValidateDeleteOpt(opt *MetricsDeleteOption) error {
return nil
}
func (s *MetricsService) ValidateSearchOpt(opt *MetricsSearchOption) error {
return nil
}
func (s *MetricsService) ValidateUpdateOpt(opt *MetricsUpdateOption) error {
return nil
}
func (s *NotificationsService) ValidateAddOpt(opt *NotificationsAddOption) error {
return nil
}
func (s *NotificationsService) ValidateListOpt(opt *NotificationsListOption) error {
return nil
}
func (s *NotificationsService) ValidateRemoveOpt(opt *NotificationsRemoveOption) error {
return nil
}
func (s *PermissionsService) ValidateAddGroupOpt(opt *PermissionsAddGroupOption) error {
return nil
}
func (s *PermissionsService) ValidateAddGroupToTemplateOpt(opt *PermissionsAddGroupToTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateAddProjectCreatorToTemplateOpt(opt *PermissionsAddProjectCreatorToTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateAddUserOpt(opt *PermissionsAddUserOption) error {
return nil
}
func (s *PermissionsService) ValidateAddUserToTemplateOpt(opt *PermissionsAddUserToTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateApplyTemplateOpt(opt *PermissionsApplyTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateBulkApplyTemplateOpt(opt *PermissionsBulkApplyTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateCreateTemplateOpt(opt *PermissionsCreateTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateDeleteTemplateOpt(opt *PermissionsDeleteTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateRemoveGroupOpt(opt *PermissionsRemoveGroupOption) error {
return nil
}
func (s *PermissionsService) ValidateRemoveGroupFromTemplateOpt(opt *PermissionsRemoveGroupFromTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateRemoveProjectCreatorFromTemplateOpt(opt *PermissionsRemoveProjectCreatorFromTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateRemoveUserOpt(opt *PermissionsRemoveUserOption) error {
return nil
}
func (s *PermissionsService) ValidateRemoveUserFromTemplateOpt(opt *PermissionsRemoveUserFromTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateSearchTemplatesOpt(opt *PermissionsSearchTemplatesOption) error {
return nil
}
func (s *PermissionsService) ValidateSetDefaultTemplateOpt(opt *PermissionsSetDefaultTemplateOption) error {
return nil
}
func (s *PermissionsService) ValidateUpdateTemplateOpt(opt *PermissionsUpdateTemplateOption) error {
return nil
}
func (s *PluginsService) ValidateInstallOpt(opt *PluginsInstallOption) error {
return nil
}
func (s *PluginsService) ValidateInstalledOpt(opt *PluginsInstalledOption) error {
return nil
}
func (s *PluginsService) ValidateUninstallOpt(opt *PluginsUninstallOption) error {
return nil
}
func (s *PluginsService) ValidateUpdateOpt(opt *PluginsUpdateOption) error {
return nil
}
func (s *ProjectAnalysesService) ValidateCreateEventOpt(opt *ProjectAnalysesCreateEventOption) error {
return nil
}
func (s *ProjectAnalysesService) ValidateDeleteOpt(opt *ProjectAnalysesDeleteOption) error {
return nil
}
func (s *ProjectAnalysesService) ValidateDeleteEventOpt(opt *ProjectAnalysesDeleteEventOption) error {
return nil
}
func (s *ProjectAnalysesService) ValidateSearchOpt(opt *ProjectAnalysesSearchOption) error {
return nil
}
func (s *ProjectAnalysesService) ValidateUpdateEventOpt(opt *ProjectAnalysesUpdateEventOption) error {
return nil
}
func (s *ProjectBadgesService) ValidateMeasureOpt(opt *ProjectBadgesMeasureOption) error {
return nil
}
func (s *ProjectBadgesService) ValidateQualityGateOpt(opt *ProjectBadgesQualityGateOption) error {
return nil
}
func (s *ProjectBranchesService) ValidateDeleteOpt(opt *ProjectBranchesDeleteOption) error {
return nil
}
func (s *ProjectBranchesService) ValidateListOpt(opt *ProjectBranchesListOption) error {
return nil
}
func (s *ProjectBranchesService) ValidateRenameOpt(opt *ProjectBranchesRenameOption) error {
return nil
}
func (s *ProjectLinksService) ValidateCreateOpt(opt *ProjectLinksCreateOption) error {
return nil
}
func (s *ProjectLinksService) ValidateDeleteOpt(opt *ProjectLinksDeleteOption) error {
return nil
}
func (s *ProjectLinksService) ValidateSearchOpt(opt *ProjectLinksSearchOption) error {
return nil
}
func (s *ProjectPullRequestsService) ValidateDeleteOpt(opt *ProjectPullRequestsDeleteOption) error {
return nil
}
func (s *ProjectPullRequestsService) ValidateListOpt(opt *ProjectPullRequestsListOption) error {
return nil
}
func (s *ProjectTagsService) ValidateSearchOpt(opt *ProjectTagsSearchOption) error {
return nil
}
func (s *ProjectTagsService) ValidateSetOpt(opt *ProjectTagsSetOption) error {
return nil
}
func (s *ProjectsService) ValidateBulkDeleteOpt(opt *ProjectsBulkDeleteOption) error {
return nil
}
func (s *ProjectsService) ValidateBulkUpdateKeyOpt(opt *ProjectsBulkUpdateKeyOption) error {
return nil
}
func (s *ProjectsService) ValidateCreateOpt(opt *ProjectsCreateOption) error {
return nil
}
func (s *ProjectsService) ValidateDeleteOpt(opt *ProjectsDeleteOption) error {
return nil
}
func (s *ProjectsService) ValidateSearchOpt(opt *ProjectsSearchOption) error {
return nil
}
func (s *ProjectsService) ValidateUpdateKeyOpt(opt *ProjectsUpdateKeyOption) error {
return nil
}
func (s *ProjectsService) ValidateUpdateVisibilityOpt(opt *ProjectsUpdateVisibilityOption) error {
return nil
}
func (s *QualitygatesService) ValidateCopyOpt(opt *QualitygatesCopyOption) error {
return nil
}
func (s *QualitygatesService) ValidateCreateOpt(opt *QualitygatesCreateOption) error {
return nil
}
func (s *QualitygatesService) ValidateCreateConditionOpt(opt *QualitygatesCreateConditionOption) error {
return nil
}
func (s *QualitygatesService) ValidateDeleteConditionOpt(opt *QualitygatesDeleteConditionOption) error {
return nil
}
func (s *QualitygatesService) ValidateDeselectOpt(opt *QualitygatesDeselectOption) error {
return nil
}
func (s *QualitygatesService) ValidateDestroyOpt(opt *QualitygatesDestroyOption) error {
return nil
}
func (s *QualitygatesService) ValidateGetByProjectOpt(opt *QualitygatesGetByProjectOption) error {
return nil
}
func (s *QualitygatesService) ValidateListOpt(opt *QualitygatesListOption) error {
return nil
}
func (s *QualitygatesService) ValidateProjectStatusOpt(opt *QualitygatesProjectStatusOption) error {
return nil
}
func (s *QualitygatesService) ValidateRenameOpt(opt *QualitygatesRenameOption) error {
return nil
}
func (s *QualitygatesService) ValidateSearchOpt(opt *QualitygatesSearchOption) error {
return nil
}
func (s *QualitygatesService) ValidateSelectOpt(opt *QualitygatesSelectOption) error {
return nil
}
func (s *QualitygatesService) ValidateSetAsDefaultOpt(opt *QualitygatesSetAsDefaultOption) error {
return nil
}
func (s *QualitygatesService) ValidateShowOpt(opt *QualitygatesShowOption) error {
return nil
}
func (s *QualitygatesService) ValidateUpdateConditionOpt(opt *QualitygatesUpdateConditionOption) error {
return nil
}
func (s *QualityProfilesService) ValidateActivateRuleOpt(opt *QualityProfilesActivateRuleOption) error {
return nil
}
func (s *QualityProfilesService) ValidateActivateRulesOpt(opt *QualityProfilesActivateRulesOption) error {
return nil
}
func (s *QualityProfilesService) ValidateAddProjectOpt(opt *QualityProfilesAddProjectOption) error {
return nil
}
func (s *QualityProfilesService) ValidateBackupOpt(opt *QualityProfilesBackupOption) error {
return nil
}
func (s *QualityProfilesService) ValidateChangeParentOpt(opt *QualityProfilesChangeParentOption) error {
return nil
}
func (s *QualityProfilesService) ValidateChangelogOpt(opt *QualityProfilesChangelogOption) error {
return nil
}
func (s *QualityProfilesService) ValidateCopyOpt(opt *QualityProfilesCopyOption) error {
return nil
}
func (s *QualityProfilesService) ValidateCreateOpt(opt *QualityProfilesCreateOption) error {
return nil
}
func (s *QualityProfilesService) ValidateDeactivateRuleOpt(opt *QualityProfilesDeactivateRuleOption) error {
return nil
}
func (s *QualityProfilesService) ValidateDeactivateRulesOpt(opt *QualityProfilesDeactivateRulesOption) error {
return nil
}
func (s *QualityProfilesService) ValidateDeleteOpt(opt *QualityProfilesDeleteOption) error {
return nil
}
func (s *QualityProfilesService) ValidateExportOpt(opt *QualityProfilesExportOption) error {
return nil
}
func (s *QualityProfilesService) ValidateInheritanceOpt(opt *QualityProfilesInheritanceOption) error {
return nil
}
func (s *QualityProfilesService) ValidateProjectsOpt(opt *QualityProfilesProjectsOption) error {
return nil
}
func (s *QualityProfilesService) ValidateRemoveProjectOpt(opt *QualityProfilesRemoveProjectOption) error {
return nil
}
func (s *QualityProfilesService) ValidateRenameOpt(opt *QualityProfilesRenameOption) error {
return nil
}
func (s *QualityProfilesService) ValidateRestoreOpt(opt *QualityProfilesRestoreOption) error {
return nil
}
func (s *QualityProfilesService) ValidateSearchOpt(opt *QualityProfilesSearchOption) error {
return nil
}
func (s *QualityProfilesService) ValidateSetDefaultOpt(opt *QualityProfilesSetDefaultOption) error {
return nil
}
func (s *RulesService) ValidateCreateOpt(opt *RulesCreateOption) error {
return nil
}
func (s *RulesService) ValidateDeleteOpt(opt *RulesDeleteOption) error {
return nil
}
func (s *RulesService) ValidateRepositoriesOpt(opt *RulesRepositoriesOption) error {
return nil
}
func (s *RulesService) ValidateSearchOpt(opt *RulesSearchOption) error {
return nil
}
func (s *RulesService) ValidateShowOpt(opt *RulesShowOption) error {
return nil
}
func (s *RulesService) ValidateTagsOpt(opt *RulesTagsOption) error {
return nil
}
func (s *RulesService) ValidateUpdateOpt(opt *RulesUpdateOption) error {
return nil
}
func (s *SettingsService) ValidateListDefinitionsOpt(opt *SettingsListDefinitionsOption) error {
return nil
}
func (s *SettingsService) ValidateResetOpt(opt *SettingsResetOption) error {
return nil
}
func (s *SettingsService) ValidateSetOpt(opt *SettingsSetOption) error {
return nil
}
func (s *SettingsService) ValidateValuesOpt(opt *SettingsValuesOption) error {
return nil
}
func (s *SourcesService) ValidateRawOpt(opt *SourcesRawOption) error {
return nil
}
func (s *SourcesService) ValidateSCMOpt(opt *SourcesSCMOption) error {
return nil
}
func (s *SourcesService) ValidateShowOpt(opt *SourcesShowOption) error {
return nil
}
func (s *SystemService) ValidateChangeLogLevelOpt(opt *SystemChangeLogLevelOption) error {
return nil
}
func (s *SystemService) ValidateLogsOpt(opt *SystemLogsOption) error {
return nil
}
func (s *UserGroupsService) ValidateAddUserOpt(opt *UserGroupsAddUserOption) error {
return nil
}
func (s *UserGroupsService) ValidateCreateOpt(opt *UserGroupsCreateOption) error {
return nil
}
func (s *UserGroupsService) ValidateDeleteOpt(opt *UserGroupsDeleteOption) error {
return nil
}
func (s *UserGroupsService) ValidateRemoveUserOpt(opt *UserGroupsRemoveUserOption) error {
return nil
}
func (s *UserGroupsService) ValidateSearchOpt(opt *UserGroupsSearchOption) error {
return nil
}
func (s *UserGroupsService) ValidateUpdateOpt(opt *UserGroupsUpdateOption) error {
return nil
}
func (s *UserGroupsService) ValidateUsersOpt(opt *UserGroupsUsersOption) error {
return nil
}
func (s *UserTokensService) ValidateGenerateOpt(opt *UserTokensGenerateOption) error {
return nil
}
func (s *UserTokensService) ValidateRevokeOpt(opt *UserTokensRevokeOption) error {
return nil
}
func (s *UserTokensService) ValidateSearchOpt(opt *UserTokensSearchOption) error {
return nil
}
func (s *UsersService) ValidateChangePasswordOpt(opt *UsersChangePasswordOption) error {
return nil
}
func (s *UsersService) ValidateCreateOpt(opt *UsersCreateOption) error {
return nil
}
func (s *UsersService) ValidateDeactivateOpt(opt *UsersDeactivateOption) error {
return nil
}
func (s *UsersService) ValidateGroupsOpt(opt *UsersGroupsOption) error {
return nil
}
func (s *UsersService) ValidateSearchOpt(opt *UsersSearchOption) error {
return nil
}
func (s *UsersService) ValidateUpdateOpt(opt *UsersUpdateOption) error {
return nil
}
func (s *WebhooksService) ValidateCreateOpt(opt *WebhooksCreateOption) error {
return nil
}
func (s *WebhooksService) ValidateDeleteOpt(opt *WebhooksDeleteOption) error {
return nil
}
func (s *WebhooksService) ValidateDeliveriesOpt(opt *WebhooksDeliveriesOption) error {
return nil
}
func (s *WebhooksService) ValidateDeliveryOpt(opt *WebhooksDeliveryOption) error {
return nil
}
func (s *WebhooksService) ValidateListOpt(opt *WebhooksListOption) error {
return nil
}
func (s *WebhooksService) ValidateUpdateOpt(opt *WebhooksUpdateOption) error {
return nil
}

View File

@@ -0,0 +1,184 @@
// Webhooks allow to notify external services when a project analysis is done
package sonargo
import "net/http"
type WebhooksService struct {
client *Client
}
type WebhooksCreateObject struct {
Webhook *Webhook `json:"webhook,omitempty"`
}
type Webhook struct {
Key string `json:"key,omitempty"`
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
LatestDelivery *Delivery `json:"latestDelivery,omitempty"`
}
type WebhooksDeliveriesObject struct {
Deliveries []*Delivery `json:"deliveries,omitempty"`
Paging Paging `json:"paging,omitempty"`
}
type Delivery struct {
At string `json:"at,omitempty"`
CeTaskID string `json:"ceTaskId,omitempty"`
ComponentKey string `json:"componentKey,omitempty"`
DurationMs int64 `json:"durationMs,omitempty"`
HTTPStatus int64 `json:"httpStatus,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Payload string `json:"payload,omitempty"`
Success bool `json:"success,omitempty"`
URL string `json:"url,omitempty"`
ErrorStackTrace string `json:"errorStacktrace,omitempty"`
}
type WebhooksDeliveryObject struct {
Delivery *Delivery `json:"delivery,omitempty"`
}
type WebhooksListObject struct {
Webhooks []*Webhook `json:"webhooks,omitempty"`
}
type WebhooksCreateOption struct {
Name string `url:"name,omitempty"` // Description:"Name displayed in the administration console of webhooks",ExampleValue:"My Webhook"
Project string `url:"project,omitempty"` // Description:"The key of the project that will own the webhook",ExampleValue:"my_project"
Url string `url:"url,omitempty"` // Description:"Server endpoint that will receive the webhook payload, for example 'http://my_server/foo'. If HTTP Basic authentication is used, HTTPS is recommended to avoid man in the middle attacks. Example: 'https://myLogin:myPassword@my_server/foo'",ExampleValue:"https://www.my-webhook-listener.com/sonar"
}
// Create Create a Webhook.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *WebhooksService) Create(opt *WebhooksCreateOption) (v *WebhooksCreateObject, resp *http.Response, err error) {
err = s.ValidateCreateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "webhooks/create", opt)
if err != nil {
return
}
v = new(WebhooksCreateObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type WebhooksDeleteOption struct {
Webhook string `url:"webhook,omitempty"` // Description:"The key of the webhook to be deleted,auto-generated value can be obtained through api/webhooks/create or api/webhooks/list",ExampleValue:"my_project"
}
// Delete Delete a Webhook.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *WebhooksService) Delete(opt *WebhooksDeleteOption) (resp *http.Response, err error) {
err = s.ValidateDeleteOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "webhooks/delete", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}
type WebhooksDeliveriesOption struct {
CeTaskId string `url:"ceTaskId,omitempty"` // Description:"Id of the Compute Engine task",ExampleValue:"AU-Tpxb--iU5OvuD2FLy"
ComponentKey string `url:"componentKey,omitempty"` // Description:"Key of the project",ExampleValue:"my-project"
P string `url:"p,omitempty"` // Description:"1-based page number",ExampleValue:"42"
Ps string `url:"ps,omitempty"` // Description:"Page size. Must be greater than 0 and less than 500",ExampleValue:"20"
Webhook string `url:"webhook,omitempty"` // Description:"Key of the webhook that triggered those deliveries,auto-generated value that can be obtained through api/webhooks/create or api/webhooks/list",ExampleValue:"AU-TpxcA-iU5OvuD2FLz"
}
// Deliveries Get the recent deliveries for a specified project or Compute Engine task.<br/>Require 'Administer' permission on the related project.<br/>Note that additional information are returned by api/webhooks/delivery.
func (s *WebhooksService) Deliveries(opt *WebhooksDeliveriesOption) (v *WebhooksDeliveriesObject, resp *http.Response, err error) {
err = s.ValidateDeliveriesOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "webhooks/deliveries", opt)
if err != nil {
return
}
v = new(WebhooksDeliveriesObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type WebhooksDeliveryOption struct {
DeliveryId string `url:"deliveryId,omitempty"` // Description:"Id of delivery",ExampleValue:"AU-TpxcA-iU5OvuD2FL3"
}
// Delivery Get a webhook delivery by its id.<br/>Require 'Administer System' permission.<br/>Note that additional information are returned by api/webhooks/delivery.
func (s *WebhooksService) Delivery(opt *WebhooksDeliveryOption) (v *WebhooksDeliveryObject, resp *http.Response, err error) {
err = s.ValidateDeliveryOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "webhooks/delivery", opt)
if err != nil {
return
}
v = new(WebhooksDeliveryObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type WebhooksListOption struct {
Project string `url:"project,omitempty"` // Description:"Project key",ExampleValue:"my_project"
}
// List Search for global webhooks or project webhooks. Webhooks are ordered by name.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *WebhooksService) List(opt *WebhooksListOption) (v *WebhooksListObject, resp *http.Response, err error) {
err = s.ValidateListOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("GET", "webhooks/list", opt)
if err != nil {
return
}
v = new(WebhooksListObject)
resp, err = s.client.Do(req, v)
if err != nil {
return nil, resp, err
}
return
}
type WebhooksUpdateOption struct {
Name string `url:"name,omitempty"` // Description:"new name of the webhook",ExampleValue:"My Webhook"
Url string `url:"url,omitempty"` // Description:"new url to be called by the webhook",ExampleValue:"https://www.my-webhook-listener.com/sonar"
Webhook string `url:"webhook,omitempty"` // Description:"The key of the webhook to be updated,auto-generated value can be obtained through api/webhooks/create or api/webhooks/list",ExampleValue:"my_project"
}
// Update Update a Webhook.<br>Requires 'Administer' permission on the specified project, or global 'Administer' permission.
func (s *WebhooksService) Update(opt *WebhooksUpdateOption) (resp *http.Response, err error) {
err = s.ValidateUpdateOpt(opt)
if err != nil {
return
}
req, err := s.client.NewRequest("POST", "webhooks/update", opt)
if err != nil {
return
}
resp, err = s.client.Do(req, nil)
if err != nil {
return
}
return
}

21
vendor/github.com/sony/sonyflake/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright 2015 Sony Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

183
vendor/github.com/sony/sonyflake/sonyflake.go generated vendored Normal file
View File

@@ -0,0 +1,183 @@
// Package sonyflake implements Sonyflake, a distributed unique ID generator inspired by Twitter's Snowflake.
//
// A Sonyflake ID is composed of
// 39 bits for time in units of 10 msec
// 8 bits for a sequence number
// 16 bits for a machine id
package sonyflake
import (
"errors"
"net"
"sync"
"time"
)
// These constants are the bit lengths of Sonyflake ID parts.
const (
BitLenTime = 39 // bit length of time
BitLenSequence = 8 // bit length of sequence number
BitLenMachineID = 63 - BitLenTime - BitLenSequence // bit length of machine id
)
// Settings configures Sonyflake:
//
// StartTime is the time since which the Sonyflake time is defined as the elapsed time.
// If StartTime is 0, the start time of the Sonyflake is set to "2014-09-01 00:00:00 +0000 UTC".
// If StartTime is ahead of the current time, Sonyflake is not created.
//
// MachineID returns the unique ID of the Sonyflake instance.
// If MachineID returns an error, Sonyflake is not created.
// If MachineID is nil, default MachineID is used.
// Default MachineID returns the lower 16 bits of the private IP address.
//
// CheckMachineID validates the uniqueness of the machine ID.
// If CheckMachineID returns false, Sonyflake is not created.
// If CheckMachineID is nil, no validation is done.
type Settings struct {
StartTime time.Time
MachineID func() (uint16, error)
CheckMachineID func(uint16) bool
}
// Sonyflake is a distributed unique ID generator.
type Sonyflake struct {
mutex *sync.Mutex
startTime int64
elapsedTime int64
sequence uint16
machineID uint16
}
// NewSonyflake returns a new Sonyflake configured with the given Settings.
// NewSonyflake returns nil in the following cases:
// - Settings.StartTime is ahead of the current time.
// - Settings.MachineID returns an error.
// - Settings.CheckMachineID returns false.
func NewSonyflake(st Settings) *Sonyflake {
sf := new(Sonyflake)
sf.mutex = new(sync.Mutex)
sf.sequence = uint16(1<<BitLenSequence - 1)
if st.StartTime.After(time.Now()) {
return nil
}
if st.StartTime.IsZero() {
sf.startTime = toSonyflakeTime(time.Date(2014, 9, 1, 0, 0, 0, 0, time.UTC))
} else {
sf.startTime = toSonyflakeTime(st.StartTime)
}
var err error
if st.MachineID == nil {
sf.machineID, err = lower16BitPrivateIP()
} else {
sf.machineID, err = st.MachineID()
}
if err != nil || (st.CheckMachineID != nil && !st.CheckMachineID(sf.machineID)) {
return nil
}
return sf
}
// NextID generates a next unique ID.
// After the Sonyflake time overflows, NextID returns an error.
func (sf *Sonyflake) NextID() (uint64, error) {
const maskSequence = uint16(1<<BitLenSequence - 1)
sf.mutex.Lock()
defer sf.mutex.Unlock()
current := currentElapsedTime(sf.startTime)
if sf.elapsedTime < current {
sf.elapsedTime = current
sf.sequence = 0
} else { // sf.elapsedTime >= current
sf.sequence = (sf.sequence + 1) & maskSequence
if sf.sequence == 0 {
sf.elapsedTime++
overtime := sf.elapsedTime - current
time.Sleep(sleepTime((overtime)))
}
}
return sf.toID()
}
const sonyflakeTimeUnit = 1e7 // nsec, i.e. 10 msec
func toSonyflakeTime(t time.Time) int64 {
return t.UTC().UnixNano() / sonyflakeTimeUnit
}
func currentElapsedTime(startTime int64) int64 {
return toSonyflakeTime(time.Now()) - startTime
}
func sleepTime(overtime int64) time.Duration {
return time.Duration(overtime)*10*time.Millisecond -
time.Duration(time.Now().UTC().UnixNano()%sonyflakeTimeUnit)*time.Nanosecond
}
func (sf *Sonyflake) toID() (uint64, error) {
if sf.elapsedTime >= 1<<BitLenTime {
return 0, errors.New("over the time limit")
}
return uint64(sf.elapsedTime)<<(BitLenSequence+BitLenMachineID) |
uint64(sf.sequence)<<BitLenMachineID |
uint64(sf.machineID), nil
}
func privateIPv4() (net.IP, error) {
as, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, a := range as {
ipnet, ok := a.(*net.IPNet)
if !ok || ipnet.IP.IsLoopback() {
continue
}
ip := ipnet.IP.To4()
if isPrivateIPv4(ip) {
return ip, nil
}
}
return nil, errors.New("no private ip address")
}
func isPrivateIPv4(ip net.IP) bool {
return ip != nil &&
(ip[0] == 10 || ip[0] == 172 && (ip[1] >= 16 && ip[1] < 32) || ip[0] == 192 && ip[1] == 168)
}
func lower16BitPrivateIP() (uint16, error) {
ip, err := privateIPv4()
if err != nil {
return 0, err
}
return uint16(ip[2])<<8 + uint16(ip[3]), nil
}
// Decompose returns a set of Sonyflake ID parts.
func Decompose(id uint64) map[string]uint64 {
const maskSequence = uint64((1<<BitLenSequence - 1) << BitLenMachineID)
const maskMachineID = uint64(1<<BitLenMachineID - 1)
msb := id >> 63
time := id >> (BitLenSequence + BitLenMachineID)
sequence := id & maskSequence >> BitLenMachineID
machineID := id & maskMachineID
return map[string]uint64{
"id": id,
"msb": msb,
"time": time,
"sequence": sequence,
"machine-id": machineID,
}
}

22
vendor/github.com/speps/go-hashids/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2014 Remi Gillig
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

445
vendor/github.com/speps/go-hashids/hashids.go generated vendored Normal file
View File

@@ -0,0 +1,445 @@
// Go implementation of http://www.hashids.org under MIT license
// Generates hashes from an array of integers, eg. for YouTube like hashes
// Setup: go get github.com/speps/go-hashids
// Original implementations by Ivan Akimov at https://github.com/ivanakimov
// Thanks to Rémy Oudompheng and Peter Hellberg for code review and fixes
package hashids
import (
"errors"
"fmt"
"math"
"strings"
)
const (
// Version is the version number of the library
Version string = "1.0.0"
// DefaultAlphabet is the default alphabet used by go-hashids
DefaultAlphabet string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
minAlphabetLength int = 16
sepDiv float64 = 3.5
guardDiv float64 = 12.0
)
var sepsOriginal = []rune("cfhistuCFHISTU")
// HashID contains everything needed to encode/decode hashids
type HashID struct {
alphabet []rune
minLength int
maxLengthPerNumber int
salt []rune
seps []rune
guards []rune
}
// HashIDData contains the information needed to generate hashids
type HashIDData struct {
// Alphabet is the alphabet used to generate new ids
Alphabet string
// MinLength is the minimum length of a generated id
MinLength int
// Salt is the secret used to make the generated id harder to guess
Salt string
}
// NewData creates a new HashIDData with the DefaultAlphabet already set.
func NewData() *HashIDData {
return &HashIDData{Alphabet: DefaultAlphabet}
}
// New creates a new HashID
func New() (*HashID, error) {
return NewWithData(NewData())
}
// NewWithData creates a new HashID with the provided HashIDData
func NewWithData(data *HashIDData) (*HashID, error) {
if len(data.Alphabet) < minAlphabetLength {
return nil, fmt.Errorf("alphabet must contain at least %d characters", minAlphabetLength)
}
if strings.Contains(data.Alphabet, " ") {
return nil, fmt.Errorf("alphabet may not contain spaces")
}
// Check if all characters are unique in Alphabet
uniqueCheck := make(map[rune]bool, len(data.Alphabet))
for _, a := range data.Alphabet {
if _, found := uniqueCheck[a]; found {
return nil, fmt.Errorf("duplicate character in alphabet: %s", string([]rune{a}))
}
uniqueCheck[a] = true
}
alphabet := []rune(data.Alphabet)
salt := []rune(data.Salt)
seps := duplicateRuneSlice(sepsOriginal)
// seps should contain only characters present in alphabet; alphabet should not contains seps
for i := 0; i < len(seps); i++ {
foundIndex := -1
for j, a := range alphabet {
if a == seps[i] {
foundIndex = j
break
}
}
if foundIndex == -1 {
seps = append(seps[:i], seps[i+1:]...)
i--
} else {
alphabet = append(alphabet[:foundIndex], alphabet[foundIndex+1:]...)
}
}
consistentShuffleInPlace(seps, salt)
if len(seps) == 0 || float64(len(alphabet))/float64(len(seps)) > sepDiv {
sepsLength := int(math.Ceil(float64(len(alphabet)) / sepDiv))
if sepsLength == 1 {
sepsLength++
}
if sepsLength > len(seps) {
diff := sepsLength - len(seps)
seps = append(seps, alphabet[:diff]...)
alphabet = alphabet[diff:]
} else {
seps = seps[:sepsLength]
}
}
consistentShuffleInPlace(alphabet, salt)
guardCount := int(math.Ceil(float64(len(alphabet)) / guardDiv))
var guards []rune
if len(alphabet) < 3 {
guards = seps[:guardCount]
seps = seps[guardCount:]
} else {
guards = alphabet[:guardCount]
alphabet = alphabet[guardCount:]
}
hid := &HashID{
alphabet: alphabet,
minLength: data.MinLength,
salt: salt,
seps: seps,
guards: guards,
}
// Calculate the maximum possible string length by hashing the maximum possible id
encoded, err := hid.EncodeInt64([]int64{math.MaxInt64})
if err != nil {
return nil, fmt.Errorf("Unable to encode maximum int64 to find max encoded value length: %s", err)
}
hid.maxLengthPerNumber = len(encoded)
return hid, nil
}
// Encode hashes an array of int to a string containing at least MinLength characters taken from the Alphabet.
// Use Decode using the same Alphabet and Salt to get back the array of int.
func (h *HashID) Encode(numbers []int) (string, error) {
numbers64 := make([]int64, 0, len(numbers))
for _, id := range numbers {
numbers64 = append(numbers64, int64(id))
}
return h.EncodeInt64(numbers64)
}
// EncodeInt64 hashes an array of int64 to a string containing at least MinLength characters taken from the Alphabet.
// Use DecodeInt64 using the same Alphabet and Salt to get back the array of int64.
func (h *HashID) EncodeInt64(numbers []int64) (string, error) {
if len(numbers) == 0 {
return "", errors.New("encoding empty array of numbers makes no sense")
}
for _, n := range numbers {
if n < 0 {
return "", errors.New("negative number not supported")
}
}
alphabet := duplicateRuneSlice(h.alphabet)
numbersHash := int64(0)
for i, n := range numbers {
numbersHash += (n % int64(i+100))
}
maxRuneLength := h.maxLengthPerNumber * len(numbers)
if maxRuneLength < h.minLength {
maxRuneLength = h.minLength
}
result := make([]rune, 0, maxRuneLength)
lottery := alphabet[numbersHash%int64(len(alphabet))]
result = append(result, lottery)
hashBuf := make([]rune, maxRuneLength)
buffer := make([]rune, len(alphabet)+len(h.salt)+1)
for i, n := range numbers {
buffer = buffer[:1]
buffer[0] = lottery
buffer = append(buffer, h.salt...)
buffer = append(buffer, alphabet...)
consistentShuffleInPlace(alphabet, buffer[:len(alphabet)])
hashBuf = hash(n, alphabet, hashBuf)
result = append(result, hashBuf...)
if i+1 < len(numbers) {
n %= int64(hashBuf[0]) + int64(i)
result = append(result, h.seps[n%int64(len(h.seps))])
}
}
if len(result) < h.minLength {
guardIndex := (numbersHash + int64(result[0])) % int64(len(h.guards))
result = append([]rune{h.guards[guardIndex]}, result...)
if len(result) < h.minLength {
guardIndex = (numbersHash + int64(result[2])) % int64(len(h.guards))
result = append(result, h.guards[guardIndex])
}
}
halfLength := len(alphabet) / 2
for len(result) < h.minLength {
consistentShuffleInPlace(alphabet, duplicateRuneSlice(alphabet))
result = append(alphabet[halfLength:], append(result, alphabet[:halfLength]...)...)
excess := len(result) - h.minLength
if excess > 0 {
result = result[excess/2 : excess/2+h.minLength]
}
}
return string(result), nil
}
// EncodeHex hashes a hexadecimal string to a string containing at least MinLength characters taken from the Alphabet.
// A hexadecimal string should not contain the 0x prefix.
// Use DecodeHex using the same Alphabet and Salt to get back the hexadecimal string.
//
// Each hex nibble is encoded as an integer in range [16, 31].
func (h *HashID) EncodeHex(hex string) (string, error) {
nums := make([]int, len(hex))
for i := 0; i < len(hex); i++ {
b := hex[i]
switch {
case (b >= '0') && (b <= '9'):
b -= '0'
case (b >= 'a') && (b <= 'f'):
b -= 'a' - 'A'
fallthrough
case (b >= 'A') && (b <= 'F'):
b -= ('A' - 0xA)
default:
return "", errors.New("invalid hex digit")
}
// Each int is in range [16, 31]
nums[i] = 0x10 + int(b)
}
return h.Encode(nums)
}
// DEPRECATED: Use DecodeWithError instead
// Decode unhashes the string passed to an array of int.
// It is symmetric with Encode if the Alphabet and Salt are the same ones which were used to hash.
// MinLength has no effect on Decode.
func (h *HashID) Decode(hash string) []int {
result, err := h.DecodeWithError(hash)
if err != nil {
panic(err)
}
return result
}
// Decode unhashes the string passed to an array of int.
// It is symmetric with Encode if the Alphabet and Salt are the same ones which were used to hash.
// MinLength has no effect on Decode.
func (h *HashID) DecodeWithError(hash string) ([]int, error) {
result64, err := h.DecodeInt64WithError(hash)
if err != nil {
return nil, err
}
result := make([]int, 0, len(result64))
for _, id := range result64 {
result = append(result, int(id))
}
return result, nil
}
// DEPRECATED: Use DecodeInt64WithError instead
// DecodeInt64 unhashes the string passed to an array of int64.
// It is symmetric with EncodeInt64 if the Alphabet and Salt are the same ones which were used to hash.
// MinLength has no effect on DecodeInt64.
func (h *HashID) DecodeInt64(hash string) []int64 {
result, err := h.DecodeInt64WithError(hash)
if err != nil {
panic(err)
}
return result
}
// DecodeInt64 unhashes the string passed to an array of int64.
// It is symmetric with EncodeInt64 if the Alphabet and Salt are the same ones which were used to hash.
// MinLength has no effect on DecodeInt64.
func (h *HashID) DecodeInt64WithError(hash string) ([]int64, error) {
hashes := splitRunes([]rune(hash), h.guards)
hashIndex := 0
if len(hashes) == 2 || len(hashes) == 3 {
hashIndex = 1
}
result := make([]int64, 0, 10)
hashBreakdown := hashes[hashIndex]
if len(hashBreakdown) > 0 {
lottery := hashBreakdown[0]
hashBreakdown = hashBreakdown[1:]
hashes = splitRunes(hashBreakdown, h.seps)
alphabet := duplicateRuneSlice(h.alphabet)
buffer := make([]rune, len(alphabet)+len(h.salt)+1)
for _, subHash := range hashes {
buffer = buffer[:1]
buffer[0] = lottery
buffer = append(buffer, h.salt...)
buffer = append(buffer, alphabet...)
consistentShuffleInPlace(alphabet, buffer[:len(alphabet)])
number, err := unhash(subHash, alphabet)
if err != nil {
return nil, err
}
result = append(result, number)
}
}
sanityCheck, _ := h.EncodeInt64(result)
if sanityCheck != hash {
return result, fmt.Errorf("mismatch between encode and decode: %s start %s"+
" re-encoded. result: %v", hash, sanityCheck, result)
}
return result, nil
}
// DecodeHex unhashes the string passed to a hexadecimal string.
// It is symmetric with EncodeHex if the Alphabet and Salt are the same ones which were used to hash.
//
// Each hex nibble is decoded from an integer in range [16, 31].
func (h *HashID) DecodeHex(hash string) (string, error) {
numbers, err := h.DecodeInt64WithError(hash)
if err != nil {
return "", err
}
const hex = "0123456789abcdef"
b := make([]byte, len(numbers))
for i, n := range numbers {
if n < 0x10 || n > 0x1f {
return "", errors.New("invalid number")
}
b[i] = hex[n-0x10]
}
return string(b), nil
}
func splitRunes(input, seps []rune) [][]rune {
splitIndices := make([]int, 0)
for i, inputRune := range input {
for _, sepsRune := range seps {
if inputRune == sepsRune {
splitIndices = append(splitIndices, i)
}
}
}
result := make([][]rune, 0, len(splitIndices)+1)
inputLeft := input[:]
for _, splitIndex := range splitIndices {
splitIndex -= len(input) - len(inputLeft)
result = append(result, inputLeft[:splitIndex])
inputLeft = inputLeft[splitIndex+1:]
}
result = append(result, inputLeft)
return result
}
func hash(input int64, alphabet []rune, result []rune) []rune {
result = result[:0]
for {
r := alphabet[input%int64(len(alphabet))]
result = append(result, r)
input /= int64(len(alphabet))
if input == 0 {
break
}
}
for i := len(result)/2 - 1; i >= 0; i-- {
opp := len(result) - 1 - i
result[i], result[opp] = result[opp], result[i]
}
return result
}
func unhash(input, alphabet []rune) (int64, error) {
result := int64(0)
for _, inputRune := range input {
alphabetPos := -1
for pos, alphabetRune := range alphabet {
if inputRune == alphabetRune {
alphabetPos = pos
break
}
}
if alphabetPos == -1 {
return 0, errors.New("alphabet used for hash was different")
}
result = result*int64(len(alphabet)) + int64(alphabetPos)
}
return result, nil
}
func consistentShuffle(alphabet, salt []rune) []rune {
if len(salt) == 0 {
return alphabet
}
result := duplicateRuneSlice(alphabet)
for i, v, p := len(result)-1, 0, 0; i > 0; i-- {
p += int(salt[v])
j := (int(salt[v]) + v + p) % i
result[i], result[j] = result[j], result[i]
v = (v + 1) % len(salt)
}
return result
}
func consistentShuffleInPlace(alphabet []rune, salt []rune) {
if len(salt) == 0 {
return
}
for i, v, p := len(alphabet)-1, 0, 0; i > 0; i-- {
p += int(salt[v])
j := (int(salt[v]) + v + p) % i
alphabet[i], alphabet[j] = alphabet[j], alphabet[i]
v = (v + 1) % len(salt)
}
return
}
func duplicateRuneSlice(data []rune) []rune {
result := make([]rune, len(data))
copy(result, data)
return result
}