diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 7a4a5ceec9a..01826c7c810 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -78,9 +78,8 @@ runs: if: ${{ inputs.language == 'go' }} shell: bash run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.60.3 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.1.6 echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - go install golang.org/x/tools/cmd/goimports@v0.22.0 - name: Cache golangci-lint analysis if: ${{ inputs.language == 'go' }} diff --git a/clients/algoliasearch-client-go/.golangci.yml b/clients/algoliasearch-client-go/.golangci.yml index 6a638b3644e..3aaa7b57c40 100644 --- a/clients/algoliasearch-client-go/.golangci.yml +++ b/clients/algoliasearch-client-go/.golangci.yml @@ -1,71 +1,85 @@ -linters-settings: - govet: - enable-all: true - disable: - - fieldalignment - - revive: - rules: - - name: var-naming - disabled: true - +version: "2" +run: + concurrency: 2 linters: - enable-all: true - + default: all disable: - - godox - - bodyclose - - contextcheck - - interfacebloat - - gci - - gosmopolitan - - wsl - - varnamelen - - nlreturn + - canonicalheader + - containedctx + - copyloopvar + - cyclop + - depguard + - dupl + - dupword - err113 - - gochecknoglobals - - exhaustruct - exhaustive - - depguard - - lll + - exhaustruct - forbidigo - - gochecknoinits - - cyclop - - errorlint - - gomnd - - tagliatelle - - nilnil - - stylecheck - - musttag - - errchkjson - - nonamedreturns - - inamedparam - - ineffassign - - dupword - - nestif - - goconst - funlen - - dupl - - unparam + - gochecknoglobals - gocognit - - forcetypeassert - - wastedassign + - goconst - gocyclo - - maintidx - - copyloopvar + - inamedparam - intrange - - canonicalheader + - lll + - maintidx - mnd + - nestif + - nilnil + - nonamedreturns - perfsprint - - containedctx - - # Deprecated - - execinquery - - exportloopref - -issues: - exclude-generated: disable - -run: - concurrency: 2 - timeout: 10m + - recvcheck + - tagliatelle + - varnamelen + settings: + govet: + enable-all: true + disable: + - fieldalignment + revive: + rules: + - name: var-naming + disabled: true + staticcheck: + checks: ["all", "-ST1005", "-ST1016"] + exclusions: + generated: disable + presets: + - comments + - std-error-handling + # old client is not linted + paths-except: + - algolia/abtesting + - algolia/analytics + - algolia/composition + - algolia/ingestion + - algolia/insights + - algolia/monitoring + - algolia/personalization + - algolia/query-suggestions + - algolia/recommend + - algolia/search +formatters: + enable: + - gofmt + - gofumpt + - goimports + - golines + settings: + golines: + max-len: 150 + exclusions: + generated: disable + # old client is not formatted + paths: + - algolia/abtesting + - algolia/analytics + - algolia/composition + - algolia/ingestion + - algolia/insights + - algolia/monitoring + - algolia/personalization + - algolia/query-suggestions + - algolia/recommend + - algolia/search diff --git a/clients/algoliasearch-client-go/algolia/debug/debug.go b/clients/algoliasearch-client-go/algolia/debug/debug.go index 56a237de604..2724599d219 100644 --- a/clients/algoliasearch-client-go/algolia/debug/debug.go +++ b/clients/algoliasearch-client-go/algolia/debug/debug.go @@ -30,7 +30,9 @@ func Display(input any) { if !debug { return } + start := time.Now() + var msg string switch v := input.(type) { case *http.Request: @@ -40,6 +42,7 @@ func Display(input any) { default: msg = fmt.Sprintf("do not know how to display %#v", v) } + Println(msg) fmt.Printf("took %s\n", time.Since(start)) } @@ -52,6 +55,7 @@ func Printf(format string, a ...any) { if !debug { return } + msg := fmt.Sprintf(format, a...) fmt.Printf("> ALGOLIA DEBUG: %s", msg) } diff --git a/clients/algoliasearch-client-go/algolia/debug/utils.go b/clients/algoliasearch-client-go/algolia/debug/utils.go index 8086105c3cd..5cb43f13d1e 100644 --- a/clients/algoliasearch-client-go/algolia/debug/utils.go +++ b/clients/algoliasearch-client-go/algolia/debug/utils.go @@ -16,11 +16,14 @@ func copyReadCloser(r io.ReadCloser) (io.ReadCloser, string) { if r == nil { return nil, "" } + data, err := io.ReadAll(r) _ = r.Close() + if err != nil { return nil, "" } + return io.NopCloser(bytes.NewReader(data)), string(data) } @@ -29,10 +32,12 @@ func decodeGzipContent(in string) (string, error) { if err != nil { return in, fmt.Errorf("cannot open content with gzip.Reader: %w", err) } + out, err := io.ReadAll(gr) if err != nil { return in, fmt.Errorf("cannot read content from gzip.Reader: %w", err) } + return string(out), nil } @@ -58,10 +63,12 @@ func extractBody(body io.ReadCloser, c compression.Compression) (io.ReadCloser, func prettyPrintJSON(input string) string { var b bytes.Buffer + err := json.Indent(&b, []byte(input), "\t", " ") if err != nil { return input } + return strings.TrimSuffix(b.String(), "\n") } @@ -88,8 +95,10 @@ func debugRequest(req *http.Request) string { if strings.Contains(strings.ToLower(k), "algolia") { str = strings.Repeat("*", len(str)) } + msg += fmt.Sprintf("\theader=%s:%q\n", k, str) } + msg += fmt.Sprintf("\tbody=\n\t%s\n", prettyPrintJSON(body)) return msg diff --git a/clients/algoliasearch-client-go/algolia/errs/no_more_host_to_try_err.go b/clients/algoliasearch-client-go/algolia/errs/no_more_host_to_try_err.go index fdc72b9c9d5..89b72d194a1 100644 --- a/clients/algoliasearch-client-go/algolia/errs/no_more_host_to_try_err.go +++ b/clients/algoliasearch-client-go/algolia/errs/no_more_host_to_try_err.go @@ -23,8 +23,10 @@ func (e *NoMoreHostToTryError) IntermediateNetworkErrors() []error { func (e *NoMoreHostToTryError) Error() string { if len(e.intermediateNetworkErrors) > 0 { - return fmt.Errorf("all hosts have been contacted unsuccessfully, it can either be a server or a network error or wrong appID/key credentials were used. %w", errors.Join(e.intermediateNetworkErrors...)).Error() + return fmt.Errorf("all hosts have been contacted unsuccessfully, it can either be a server or a network error or wrong appID/key credentials were used. %w", errors.Join(e.intermediateNetworkErrors...)). + Error() } + return "all hosts have been contacted unsuccessfully, it can either be a server or a network error or wrong appID/key credentials were used. You can use 'ExposeIntermediateNetworkErrors: true' in the config to investigate." } diff --git a/clients/algoliasearch-client-go/algolia/transport/configuration.go b/clients/algoliasearch-client-go/algolia/transport/configuration.go index f2c06aa0203..538c32f1905 100644 --- a/clients/algoliasearch-client-go/algolia/transport/configuration.go +++ b/clients/algoliasearch-client-go/algolia/transport/configuration.go @@ -8,7 +8,7 @@ import ( type Configuration struct { AppID string - ApiKey string + ApiKey string //nolint:staticcheck Hosts []StatefulHost DefaultHeader map[string]string diff --git a/clients/algoliasearch-client-go/algolia/transport/retry_strategy.go b/clients/algoliasearch-client-go/algolia/transport/retry_strategy.go index 860a756de10..a5e2d181033 100644 --- a/clients/algoliasearch-client-go/algolia/transport/retry_strategy.go +++ b/clients/algoliasearch-client-go/algolia/transport/retry_strategy.go @@ -2,6 +2,7 @@ package transport import ( "context" + "errors" "net" "strings" "sync" @@ -99,16 +100,19 @@ func (s *RetryStrategy) Decide(h Host, code int, err error) Outcome { if err == nil && is2xx(code) { s.markUp(h) + return Success } if isTimeoutError(err) { s.markTimeout(h) + return Retry } - if !(isZero(code) || is4xx(code) || is2xx(code)) || isNetworkError(err) { + if (!isZero(code) && !is4xx(code) && !is2xx(code)) || isNetworkError(err) { s.markDown(h) + return Retry } @@ -119,6 +123,7 @@ func (s *RetryStrategy) markUp(host Host) { for _, h := range s.hosts { if h.host == host.host { h.markUp() + return } } @@ -128,6 +133,7 @@ func (s *RetryStrategy) markTimeout(host Host) { for _, h := range s.hosts { if h.host == host.host { h.markTimeout() + return } } @@ -137,6 +143,7 @@ func (s *RetryStrategy) markDown(host Host) { for _, h := range s.hosts { if h.host == host.host { h.markDown() + return } } @@ -146,7 +153,9 @@ func isNetworkError(err error) bool { if err == nil { return false } - _, ok := err.(net.Error) + + var netErr net.Error + ok := errors.As(err, &netErr) // We need to ensure that the error is a net.Error but not a // context.DeadlineExceeded error (which is actually a net.Error), because // we do not want to consider context.DeadlineExceeded as an error. @@ -157,6 +166,7 @@ func isTimeoutError(err error) bool { if err == nil { return false } + return strings.Contains(err.Error(), context.DeadlineExceeded.Error()) } diff --git a/clients/algoliasearch-client-go/algolia/transport/transport.go b/clients/algoliasearch-client-go/algolia/transport/transport.go index 018a9ff252e..28ad9b60a26 100644 --- a/clients/algoliasearch-client-go/algolia/transport/transport.go +++ b/clients/algoliasearch-client-go/algolia/transport/transport.go @@ -94,6 +94,7 @@ func (t *Transport) Request(ctx context.Context, req *http.Request, k call.Kind, // already cancelled. if ctx.Err() != nil { cancel() + return res, nil, err } @@ -101,22 +102,28 @@ func (t *Transport) Request(ctx context.Context, req *http.Request, k call.Kind, case Success, Failure: body, errBody := io.ReadAll(res.Body) errClose := res.Body.Close() + cancel() + res.Body = io.NopCloser(bytes.NewBuffer(body)) if errBody != nil { - return res, nil, fmt.Errorf("cannot read body: %v", errBody) + return res, nil, fmt.Errorf("cannot read body: %w", errBody) } + if errClose != nil { - return res, nil, fmt.Errorf("cannot close response's body: %v", errClose) + return res, nil, fmt.Errorf("cannot close response's body: %w", errClose) } + return res, body, err default: if err != nil { intermediateNetworkErrors = append(intermediateNetworkErrors, err) } + if res != nil && res.Body != nil { if err = res.Body.Close(); err != nil { cancel() + return res, nil, fmt.Errorf("cannot close response's body before retry: %w", err) } } @@ -142,7 +149,9 @@ func (t *Transport) request(req *http.Request, host Host, timeout time.Duration, if err != nil { msg := fmt.Sprintf("cannot perform request:\n\terror=%v\n\tmethod=%s\n\turl=%s", err, req.Method, req.URL) + var nerr net.Error + if errors.As(err, &nerr) { // Because net.Error and error have different meanings for the // retry strategy, we cannot simply return a new error, which @@ -154,6 +163,7 @@ func (t *Transport) request(req *http.Request, host Host, timeout time.Duration, } else { err = errors.New(msg) } + return nil, err } @@ -164,5 +174,6 @@ func shouldCompress(c compression.Compression, method string, body any) bool { isValidMethod := method == http.MethodPut || method == http.MethodPost isCompressionEnabled := c != compression.NONE isBodyNonEmpty := body != nil + return isCompressionEnabled && isValidMethod && isBodyNonEmpty } diff --git a/clients/algoliasearch-client-go/algolia/transport/utils.go b/clients/algoliasearch-client-go/algolia/transport/utils.go index 14fd91f59ce..e988010c749 100644 --- a/clients/algoliasearch-client-go/algolia/transport/utils.go +++ b/clients/algoliasearch-client-go/algolia/transport/utils.go @@ -8,9 +8,11 @@ func Shuffle(hosts []StatefulHost) []StatefulHost { if hosts == nil { return nil } + shuffled := make([]StatefulHost, len(hosts)) for i, v := range rand.Perm(len(hosts)) { shuffled[i] = hosts[v] } + return shuffled } diff --git a/clients/algoliasearch-client-go/algolia/utils/utils.go b/clients/algoliasearch-client-go/algolia/utils/utils.go index 317a2eb9758..84a57fe7584 100644 --- a/clients/algoliasearch-client-go/algolia/utils/utils.go +++ b/clients/algoliasearch-client-go/algolia/utils/utils.go @@ -58,6 +58,7 @@ func IsNilOrEmpty(i any) bool { if i == nil { return true } + switch reflect.TypeOf(i).Kind() { case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: return reflect.ValueOf(i).IsNil() @@ -78,11 +79,13 @@ func ParameterToString(obj any) string { objKind := reflect.TypeOf(obj).Kind() if objKind == reflect.Slice { var result []string + sliceValue := reflect.ValueOf(obj) for i := 0; i < sliceValue.Len(); i++ { element := sliceValue.Index(i).Interface() result = append(result, ParameterToString(element)) } + return strings.Join(result, ",") } @@ -101,5 +104,6 @@ func ParameterToString(obj any) string { func HasKey[T any](m map[string]T, key string) bool { _, ok := m[key] + return ok } diff --git a/scripts/docker/Dockerfile.base b/scripts/docker/Dockerfile.base index bf3ae6c878c..5d2c30df9c6 100644 --- a/scripts/docker/Dockerfile.base +++ b/scripts/docker/Dockerfile.base @@ -49,8 +49,7 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH" # Go COPY --from=go-builder /usr/local/go/ /usr/local/go/ RUN echo "export PATH=$PATH:/usr/local/go/bin:/root/go/bin" >> ~/.profile && source ~/.profile \ - && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.60.3 \ - && go install golang.org/x/tools/cmd/goimports@v0.22.0 + && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.1.6 # Dart diff --git a/scripts/formatter.ts b/scripts/formatter.ts index c8431a711ad..65175ddd50a 100644 --- a/scripts/formatter.ts +++ b/scripts/formatter.ts @@ -28,7 +28,7 @@ export async function formatter(language: string, cwd: string): Promise { } break; case 'go': - await run('goimports -w . && golangci-lint run --fix', { cwd, language }); + await run('golangci-lint fmt && golangci-lint run --fix', { cwd, language }); break; case 'java': await run( diff --git a/specs/ingestion/common/schemas/event.yml b/specs/ingestion/common/schemas/event.yml index c8083ad51be..9f3a7f7aaf6 100644 --- a/specs/ingestion/common/schemas/event.yml +++ b/specs/ingestion/common/schemas/event.yml @@ -1,6 +1,6 @@ Event: type: object - description: An event describe a step of the task execution flow.. + description: An event describe a step of the task execution flow. additionalProperties: false properties: eventID: diff --git a/specs/search/paths/rules/common/schemas.yml b/specs/search/paths/rules/common/schemas.yml index 938c67c07a4..52dd3817337 100644 --- a/specs/search/paths/rules/common/schemas.yml +++ b/specs/search/paths/rules/common/schemas.yml @@ -104,7 +104,7 @@ consequence: description: | Whether promoted records must match an active filter for the consequence to be applied. - This ensures that user actions (filtering the search) are given a higher precendence. + This ensures that user actions (filtering the search) are given a higher precedence. For example, if you promote a record with the `color: red` attribute, and the user filters the search for `color: blue`, the "red" record won't be shown. hide: @@ -287,7 +287,7 @@ automaticFacetFilter: description: | Whether the filter is disjunctive or conjunctive. - If true the filter has multiple matches, multiple occurences are combined with the logical `OR` operation. - If false, multiple occurences are combined with the logical `AND` operation. + If true the filter has multiple matches, multiple occurrences are combined with the logical `OR` operation. + If false, multiple occurrences are combined with the logical `AND` operation. required: - facet diff --git a/templates/go/api.mustache b/templates/go/api.mustache index 6e55e84051a..ee274a8a6a2 100644 --- a/templates/go/api.mustache +++ b/templates/go/api.mustache @@ -53,7 +53,7 @@ type config struct { } type RequestOption interface { - apply(*config) + apply(c *config) } type requestOption func(*config) @@ -227,7 +227,7 @@ func WithMaxRetries(maxRetries int) iterableOption { }) } -// WithTimeout he function to decide how long to wait between retries. Default to min(retryCount * 200, 5000) +// WithTimeout he function to decide how long to wait between retries. Default to min(retryCount * 200, 5000). func WithTimeout(timeout func(int) time.Duration) iterableOption { return iterableOption(func(c *config) { c.timeout = timeout @@ -268,7 +268,7 @@ func (r requestOption) waitForApiKey() {} func (i iterableOption) waitForApiKey() {} -// WithApiKey necessary to know if an `update` operation has been processed, compare fields of the response with it. (optional - mandatory if operation is UPDATE) +// WithApiKey necessary to know if an `update` operation has been processed, compare fields of the response with it. (optional - mandatory if operation is UPDATE). func WithApiKey(apiKey *ApiKey) waitForApiKeyOption { return waitForApiKeyOption(func(c *config) { c.apiKey = apiKey @@ -358,7 +358,7 @@ type {{operationId}}Options struct { } {{#isDeprecated}} -// Deprecated: {{operationId}}Options is deprecated +// Deprecated: {{operationId}}Options is deprecated. {{/isDeprecated}} // New{{operationId}}Options creates an instance of the {{operationId}}Options used to add optional parameters to {{operationId}}WithOptions. func New{{{operationId}}}Options() *{{operationId}}Options { @@ -368,7 +368,7 @@ func New{{{operationId}}}Options() *{{operationId}}Options { {{#optionalParams}} // With{{#lambda.titlecase}}{{baseName}}{{/lambda.titlecase}} {{#description}}{{{.}}}{{/description}}{{^description}}adds the {{paramName}} to the Api{{operationId}}Request and returns the request for chaining.{{/description}} {{#isDeprecated}} -// Deprecated: With{{#lambda.titlecase}}{{baseName}}{{/lambda.titlecase}} is deprecated +// Deprecated: With{{#lambda.titlecase}}{{baseName}}{{/lambda.titlecase}} is deprecated. {{/isDeprecated}} func (o *{{operationId}}Options) With{{#lambda.titlecase}}{{baseName}}{{/lambda.titlecase}}({{paramName}} {{#isModel}}*{{/isModel}}{{{dataType}}}) *{{operationId}}Options { o.{{nameInPascalCase}} = {{^isModel}}{{^isMap}}&{{/isMap}}{{/isModel}}{{paramName}} @@ -399,7 +399,7 @@ func (o *{{operationId}}Options) With{{#lambda.titlecase}}{{baseName}}{{/lambda. // - opts - Optional parameters for the API call (e.g. WithHeaderParam, WithReadTimeout...) {{#isDeprecated}} // -// Deprecated: {{operationId}} is deprecated +// Deprecated: {{operationId}} is deprecated. {{/isDeprecated}} func (c *APIClient) {{nickname}}(ctx context.Context, {{#requiredParams}}{{paramName}} {{#required}}{{#isModel}}*{{/isModel}}{{/required}}{{^required}}{{^isMap}}*{{/isMap}}{{/required}}{{{dataType}}}, {{/requiredParams}}{{#hasOptionalParams}}optionalParams *{{operationId}}Options, {{/hasOptionalParams}}opts ...RequestOption) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}error) { {{#returnType}} @@ -413,6 +413,7 @@ func (c *APIClient) {{nickname}}(ctx context.Context, {{#requiredParams}}{{param if res == nil { return {{#returnType}}returnValue, {{/returnType}}reportError("res is nil") } + defer res.Body.Close() if res.StatusCode >= 300 { return {{#returnType}}returnValue, {{/returnType}}c.decodeError(res, resBody) @@ -450,7 +451,7 @@ func (c *APIClient) {{nickname}}(ctx context.Context, {{#requiredParams}}{{param // - opts - Optional parameters for the API call (e.g. WithHeaderParam, WithReadTimeout...) {{#isDeprecated}} // -// Deprecated: {{operationId}} is deprecated +// Deprecated: {{operationId}} is deprecated. {{/isDeprecated}} func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#requiredParams}}{{paramName}} {{#required}}{{#isModel}}*{{/isModel}}{{/required}}{{^required}}{{^isMap}}*{{/isMap}}{{/required}}{{{dataType}}}, {{/requiredParams}}{{#hasOptionalParams}}optionalParams *{{operationId}}Options, {{/hasOptionalParams}}opts ...RequestOption) (*http.Response, []byte, error) { {{#vendorExtensions}} diff --git a/templates/go/client.mustache b/templates/go/client.mustache index 5e28c339db3..1b86e1e6531 100644 --- a/templates/go/client.mustache +++ b/templates/go/client.mustache @@ -122,28 +122,13 @@ func getUserAgent() string { return fmt.Sprintf("Algolia for Go ({{{packageVersion}}}); Go (%s); {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}} ({{{packageVersion}}})", runtime.Version()) } -// AddDefaultHeader adds a new HTTP header to the default header in the request +// AddDefaultHeader adds a new HTTP header to the default header in the request. func (c *APIClient) AddDefaultHeader(key string, value string) { c.cfg.DefaultHeader[key] = value } -// callAPI do the request. -func (c *APIClient) callAPI(request *http.Request, useReadTransporter bool, requestConfiguration transport.RequestConfiguration) (*http.Response, []byte, error) { - callKind := call.Write - if useReadTransporter || request.Method == http.MethodGet { - callKind = call.Read - } - - resp, body, err := c.transport.Request(request.Context(), request, callKind, requestConfiguration) - if err != nil { - return nil, nil, fmt.Errorf("failed to do request: %w", err) - } - - return resp, body, nil -} - -// Allow modification of underlying config for alternate implementations and testing -// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior +// Allow modification of underlying config for alternate implementations and testing. +// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior. func (c *APIClient) GetConfiguration() *{{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration { return c.cfg } @@ -159,7 +144,22 @@ func (c *APIClient) SetClientApiKey(apiKey string) error { return nil } -// prepareRequest build the request +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request, useReadTransporter bool, requestConfiguration transport.RequestConfiguration) (*http.Response, []byte, error) { + callKind := call.Write + if useReadTransporter || request.Method == http.MethodGet { + callKind = call.Read + } + + resp, body, err := c.transport.Request(request.Context(), request, callKind, requestConfiguration) + if err != nil { + return nil, nil, fmt.Errorf("failed to do request: %w", err) + } + + return resp, body, nil +} + +// prepareRequest builds the request. func (c *APIClient) prepareRequest( ctx context.Context, path string, method string, @@ -278,12 +278,12 @@ func (c *APIClient) decodeError(res *http.Response, body []byte) error { return apiErr } -// Prevent trying to import "fmt" +// Prevent trying to import "fmt". func reportError(format string, a ...any) error { return fmt.Errorf(format, a...) } -// Set request body from an any +// Set request body from an any. func setBody(body any, c compression.Compression) (*bytes.Buffer, error) { if body == nil { return nil, nil @@ -322,9 +322,9 @@ func setBody(body any, c compression.Compression) (*bytes.Buffer, error) { } type APIError struct { - Message string - Status int - AdditionalProperties map[string]any + Message string `json:"message"` + Status int `json:"status"` + AdditionalProperties map[string]any `json:"-"` } func (e APIError) Error() string { diff --git a/templates/go/configuration.mustache b/templates/go/configuration.mustache index d7bbae8f79c..08d6fca0015 100644 --- a/templates/go/configuration.mustache +++ b/templates/go/configuration.mustache @@ -18,7 +18,7 @@ const ( ) {{/hasRegionalHost}} -// {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration stores the configuration of the API client +// {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration stores the configuration of the API client. type {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration struct { transport.Configuration diff --git a/templates/go/guides/search/deleteMultipleIndices.mustache b/templates/go/guides/search/deleteMultipleIndices.mustache index 2e772b22cae..e003f223b01 100644 --- a/templates/go/guides/search/deleteMultipleIndices.mustache +++ b/templates/go/guides/search/deleteMultipleIndices.mustache @@ -19,8 +19,8 @@ func deleteMultipleIndices() { } // Primary indices don't have a `primary` key - primaryIndices := make([]search.FetchedIndex, len(indices.Items)) - replicaIndices := make([]search.FetchedIndex, len(indices.Items)) + primaryIndices := make([]search.FetchedIndex, 0, len(indices.Items)) + replicaIndices := make([]search.FetchedIndex, 0, len(indices.Items)) for _, index := range indices.Items { if index.Primary == nil { @@ -32,7 +32,7 @@ func deleteMultipleIndices() { // Delete primary indices first if len(primaryIndices) > 0 { - requests := make([]search.MultipleBatchRequest, len(primaryIndices)) + requests := make([]search.MultipleBatchRequest, 0, len(primaryIndices)) for _, index := range primaryIndices { requests = append(requests, search.MultipleBatchRequest{ @@ -51,7 +51,7 @@ func deleteMultipleIndices() { // Now, delete replica indices if len(replicaIndices) > 0 { - requests := make([]search.MultipleBatchRequest, len(primaryIndices)) + requests := make([]search.MultipleBatchRequest, 0, len(primaryIndices)) for _, index := range primaryIndices { requests = append(requests, search.MultipleBatchRequest{ diff --git a/templates/go/guides/search/mcmSearchWithout.mustache b/templates/go/guides/search/mcmSearchWithout.mustache index be1b99605e9..cae06a50ea2 100644 --- a/templates/go/guides/search/mcmSearchWithout.mustache +++ b/templates/go/guides/search/mcmSearchWithout.mustache @@ -13,7 +13,7 @@ func mcmSearchWithout() { return "", nil // Implement your logic here } - getIndexingApiKeyFor := func(_ string) (string, error) { + getIndexingAPIKeyFor := func(_ string) (string, error) { return "", nil // Implement your logic here } @@ -25,7 +25,7 @@ func mcmSearchWithout() { return } - apiKey, err := getIndexingApiKeyFor("user42") + apiKey, err := getIndexingAPIKeyFor("user42") if err != nil { fmt.Println(err) return diff --git a/templates/go/guides/search/saveImageClassifications.mustache b/templates/go/guides/search/saveImageClassifications.mustache index 32d1df0b72a..0c2aed4908b 100644 --- a/templates/go/guides/search/saveImageClassifications.mustache +++ b/templates/go/guides/search/saveImageClassifications.mustache @@ -14,7 +14,7 @@ func saveImageClassifications() { Objects []map[string]interface{} `json:"objects"` } - getImageLabels := func(imageURL, objectID string, scoreLimit float64) Image { + getImageLabels := func(imageURL, objectID string, _scoreLimit float64) Image { // Implement your image classification logic here return Image{ ImageURL: imageURL, diff --git a/templates/go/guides/search/saveObjectsModified.mustache b/templates/go/guides/search/saveObjectsModified.mustache index 803964a5ad8..3083edb28ee 100644 --- a/templates/go/guides/search/saveObjectsModified.mustache +++ b/templates/go/guides/search/saveObjectsModified.mustache @@ -24,11 +24,11 @@ func saveObjectsModified() { panic(err) } - records := make([]map[string]any, len(products)) + records := make([]map[string]any, 0, len(products)) for _, product := range products { reference := product["product_reference"].(string) - suffixes := make([]string, len(reference)-1) + suffixes := make([]string, 0, len(reference)-1) for i := len(reference); i > 1; i-- { suffixes = append(suffixes, reference[i:]) diff --git a/templates/go/guides/search/searchWithGAToken.mustache b/templates/go/guides/search/searchWithGAToken.mustache index 8d503f22b87..5328f7220a2 100644 --- a/templates/go/guides/search/searchWithGAToken.mustache +++ b/templates/go/guides/search/searchWithGAToken.mustache @@ -8,14 +8,14 @@ import ( {{> snippets/import}} -func getGoogleAnalyticsUserIdFromBrowserCookie(_ string) (string, error) { +func getGoogleAnalyticsUserIDFromBrowserCookie(_ string) (string, error) { return "", nil // Implement your logic here } func searchWithGAToken() { {{> snippets/init}} - userToken, err := getGoogleAnalyticsUserIdFromBrowserCookie("_ga") + userToken, err := getGoogleAnalyticsUserIDFromBrowserCookie("_ga") if err != nil { panic(err) } diff --git a/templates/go/guides/search/searchWithRuleContextBuyer.mustache b/templates/go/guides/search/searchWithRuleContextBuyer.mustache index c2f4b4ac95d..2306e8a414c 100644 --- a/templates/go/guides/search/searchWithRuleContextBuyer.mustache +++ b/templates/go/guides/search/searchWithRuleContextBuyer.mustache @@ -8,7 +8,7 @@ import ( {{> snippets/import}} -func getBuyerAccountId() (string, error) { +func getBuyerAccountID() (string, error) { return "", nil // Implement your logic here } @@ -16,7 +16,7 @@ func searchWithRuleContextBuyer() { {{> snippets/init}} // get the buyer account information - buyer, err := getBuyerAccountId() + buyer, err := getBuyerAccountID() if err != nil { panic(err) } diff --git a/templates/go/guides/search/setSettingsThenSaveObjects.mustache b/templates/go/guides/search/setSettingsThenSaveObjects.mustache index c0e7c4decca..206d06dece4 100644 --- a/templates/go/guides/search/setSettingsThenSaveObjects.mustache +++ b/templates/go/guides/search/setSettingsThenSaveObjects.mustache @@ -12,7 +12,7 @@ func getAppIDFor(_ string) (string, error) { return "", nil // Implement your logic here } -func getIndexingApiKeyFor(_ string) (string, error) { +func getIndexingAPIKeyFor(_ string) (string, error) { return "", nil // Implement your logic here } @@ -28,7 +28,7 @@ func setSettingsThenSaveObjects() { return } - apiKey, err := getIndexingApiKeyFor(playlist["user"].(string)) + apiKey, err := getIndexingAPIKeyFor(playlist["user"].(string)) if err != nil { fmt.Println(err) return diff --git a/templates/go/model.mustache b/templates/go/model.mustache index 890a350a7ff..76e8874751f 100644 --- a/templates/go/model.mustache +++ b/templates/go/model.mustache @@ -17,7 +17,7 @@ import ( {{> model_enum}} {{/isEnum}} {{^isEnum}} -{{#oneOf}}{{#-first}}{{> model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{> model_anyof}}{{/-first}}{{/anyOf}}{{^anyOf}}{{> model_simple}}{{/anyOf}}{{/oneOf}} +{{#oneOf}}{{#-first}}{{> model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{^anyOf}}{{> model_simple}}{{/anyOf}}{{/oneOf}} {{/isEnum}} {{/model}} {{/models}} diff --git a/templates/go/model_anyof.mustache b/templates/go/model_anyof.mustache deleted file mode 100644 index 35aaa0c03ce..00000000000 --- a/templates/go/model_anyof.mustache +++ /dev/null @@ -1,50 +0,0 @@ -// {{classname}} {{{description}}}{{^description}}struct for {{{classname}}}{{/description}} -type {{classname}} struct { - {{#anyOf}} - {{{.}}} *{{{.}}} - {{/anyOf}} -} - -// Unmarshal JSON data into any of the pointers in the struct -func (dst *{{classname}}) UnmarshalJSON(data []byte) error { - var err error - {{#isNullable}} - // this object is nullable so check if the payload is null or empty string - if string(data) == "" || string(data) == "{}" { - return nil - } - - {{/isNullable}} - {{#anyOf}} - // try to unmarshal JSON data into {{{.}}} - err = json.Unmarshal(data, &dst.{{{.}}}); - if err == nil { - json{{{.}}}, _ := json.Marshal(dst.{{{.}}}) - if string(json{{{.}}}) == "{}" { // empty struct - dst.{{{.}}} = nil - } else { - return nil // data stored in dst.{{{.}}}, return on the first match - } - } else { - dst.{{{.}}} = nil - } - - {{/anyOf}} - return fmt.Errorf("Data failed to match schemas in anyOf({{classname}})") -} - -// Marshal data from the first non-nil pointers in the struct to JSON -func (src *{{classname}}) MarshalJSON() ([]byte, error) { -{{#anyOf}} - if src.{{{.}}} != nil { - serialized, err := json.Marshal(&src.{{{.}}}) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal any of {{.}} of {{classname}}: %w", err) - } - - return serialized, nil - } - -{{/anyOf}} - return nil, nil // no data in anyOf schemas -} diff --git a/templates/go/model_enum.mustache b/templates/go/model_enum.mustache index cb91512b4d6..01a74a099b1 100644 --- a/templates/go/model_enum.mustache +++ b/templates/go/model_enum.mustache @@ -1,7 +1,7 @@ -// {{{classname}}} {{{description}}}{{^description}}the model '{{{classname}}}'{{/description}} +// {{{classname}}} {{{description}}}{{^description}}the model '{{{classname}}}'.{{/description}} type {{{classname}}} {{{format}}}{{^format}}{{dataType}}{{/format}} -// List of {{{name}}} +// List of {{{name}}}. const ( {{#allowableValues}} {{#enumVars}} @@ -12,7 +12,7 @@ const ( {{/allowableValues}} ) -// All allowed values of {{{classname}}} enum +// All allowed values of {{{classname}}} enum. var Allowed{{{classname}}}EnumValues = []{{{classname}}}{ {{#allowableValues}} {{#enumVars}} @@ -21,6 +21,17 @@ var Allowed{{{classname}}}EnumValues = []{{{classname}}}{ {{/allowableValues}} } +// New{{{classname}}}FromValue returns a pointer to a valid {{{classname}}}. +// for the value passed as argument, or an error if the value passed is not allowed by the enum. +func New{{{classname}}}FromValue(v {{{format}}}{{^format}}{{dataType}}{{/format}}) (*{{{classname}}}, error) { + ev := {{{classname}}}(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for {{{classname}}}: valid values are %v", v, Allowed{{{classname}}}EnumValues) + } +} + func (v *{{{classname}}}) UnmarshalJSON(src []byte) error { var value {{{format}}}{{^format}}{{dataType}}{{/format}} err := json.Unmarshal(src, &value) @@ -38,17 +49,6 @@ func (v *{{{classname}}}) UnmarshalJSON(src []byte) error { return fmt.Errorf("%+v is not a valid {{classname}}", value) } -// New{{{classname}}}FromValue returns a pointer to a valid {{{classname}}} -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func New{{{classname}}}FromValue(v {{{format}}}{{^format}}{{dataType}}{{/format}}) (*{{{classname}}}, error) { - ev := {{{classname}}}(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for {{{classname}}}: valid values are %v", v, Allowed{{{classname}}}EnumValues) - } -} - // IsValid return true if the value is valid for the enum, false otherwise. func (v {{{classname}}}) IsValid() bool { for _, existing := range Allowed{{{classname}}}EnumValues { @@ -59,7 +59,7 @@ func (v {{{classname}}}) IsValid() bool { return false } -// Ptr returns reference to {{{name}}} value +// Ptr returns reference to {{{name}}} value. func (v {{{classname}}}) Ptr() *{{{classname}}} { return &v -} +} \ No newline at end of file diff --git a/templates/go/model_oneof.mustache b/templates/go/model_oneof.mustache index 483e1499613..1597649b2cb 100644 --- a/templates/go/model_oneof.mustache +++ b/templates/go/model_oneof.mustache @@ -1,4 +1,4 @@ -// {{classname}} - {{{description}}}{{^description}}struct for {{{classname}}}{{/description}} +// {{classname}} - {{{description}}}{{^description}}struct for {{{classname}}}.{{/description}} type {{classname}} struct { {{#oneOf}} {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} *{{{.}}} @@ -6,7 +6,7 @@ type {{classname}} struct { } {{#composedSchemas.oneOf}} -// {{{datatypeWithEnum}}}As{{classname}} is a convenience function that returns {{{datatypeWithEnum}}} wrapped in {{classname}} +// {{{datatypeWithEnum}}}As{{classname}} is a convenience function that returns {{{datatypeWithEnum}}} wrapped in {{classname}}. func {{#lambda.type-to-name}}{{{datatypeWithEnum}}}{{/lambda.type-to-name}}As{{classname}}(v {{#isModel}}*{{/isModel}}{{{datatypeWithEnum}}}) *{{classname}} { return &{{classname}}{ {{#lambda.type-to-name}}{{{datatypeWithEnum}}}{{/lambda.type-to-name}}: {{^isModel}}&{{/isModel}}v, @@ -15,7 +15,7 @@ func {{#lambda.type-to-name}}{{{datatypeWithEnum}}}{{/lambda.type-to-name}}As{{c {{/composedSchemas.oneOf}} -// Unmarshal JSON data into one of the pointers in the struct +// Unmarshal JSON data into one of the pointers in the struct. func (dst *{{classname}}) UnmarshalJSON(data []byte) error { var err error {{#isNullable}} @@ -46,10 +46,10 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { {{/vendorExtensions.x-discriminator-fields.size}} {{/composedSchemas.oneOf}} - return fmt.Errorf("Data failed to match schemas in oneOf({{classname}})") + return fmt.Errorf("data failed to match schemas in oneOf({{classname}})") } -// Marshal data from the first non-nil pointers in the struct to JSON +// Marshal data from the first non-nil pointers in the struct to JSON. func (src {{classname}}) MarshalJSON() ([]byte, error) { {{#oneOf}} if src.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} != nil { @@ -65,7 +65,7 @@ func (src {{classname}}) MarshalJSON() ([]byte, error) { return nil, nil // no data in oneOf schemas } -// Get the actual instance +// Get the actual instance. func (obj {{classname}}) GetActualInstance() (any) { {{#oneOf}} if obj.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} != nil { diff --git a/templates/go/model_simple.mustache b/templates/go/model_simple.mustache index 8c28c2c0aa5..68fb99838de 100644 --- a/templates/go/model_simple.mustache +++ b/templates/go/model_simple.mustache @@ -1,4 +1,4 @@ -// {{classname}} {{{description}}}{{^description}}struct for {{{classname}}}{{/description}} +// {{classname}} {{{description}}}{{^description}}struct for {{{classname}}}.{{/description}} type {{classname}} struct { {{#parent}} {{^isMap}} @@ -15,12 +15,12 @@ type {{classname}} struct { // {{{.}}} {{/description}} {{#deprecated}} - // Deprecated + // Deprecated: {{name}} is deprecated. {{/deprecated}} {{name}} {{^required}}{{^isNullable}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"` {{/vars}} {{#isAdditionalPropertiesTrue}} - AdditionalProperties map[string]any + AdditionalProperties map[string]any `json:"-"` {{/isAdditionalPropertiesTrue}} } @@ -73,7 +73,7 @@ func NewEmpty{{classname}}() *{{classname}} { // If the value is explicit nil, the zero value for {{vendorExtensions.x-go-base-type}} will be returned. {{/isNullable}} {{#deprecated}} -// Deprecated +// Deprecated: Get{{name}} is deprecated. {{/deprecated}} func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { if o == nil{{#isNullable}}{{^vendorExtensions.x-golang-is-container}} || o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { @@ -100,7 +100,7 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { // NOTE: If the value is an explicit nil, `nil, true` will be returned. {{/isNullable}} {{#deprecated}} -// Deprecated +// Deprecated: Get{{name}}Ok is deprecated. {{/deprecated}} func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) { if o == nil{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { @@ -121,7 +121,7 @@ func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/is // Set{{name}} sets field value. {{#deprecated}} -// Deprecated +// Deprecated: Set{{name}} is deprecated. {{/deprecated}} func (o *{{classname}}) Set{{name}}(v {{#isModel}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isModel}}{{vendorExtensions.x-go-base-type}}) *{{classname}} { {{#isNullable}} @@ -142,7 +142,7 @@ func (o *{{classname}}) Set{{name}}(v {{#isModel}}{{^isArray}}{{^isFreeFormObjec {{^required}} // Get{{name}} returns the {{name}} field value if set, zero value otherwise{{#isNullable}} (both if not set or set to explicit null){{/isNullable}}. {{#deprecated}} -// Deprecated +// Deprecated: Get{{name}} is deprecated. {{/deprecated}} func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { if o == nil{{^isNullable}} || o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-is-container}} || o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { @@ -168,7 +168,7 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { // NOTE: If the value is an explicit nil, `nil, true` will be returned. {{/isNullable}} {{#deprecated}} -// Deprecated +// Deprecated: Get{{name}}Ok is deprecated. {{/deprecated}} func (o *{{classname}}) Get{{name}}Ok() ({{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{vendorExtensions.x-go-base-type}}, bool) { if o == nil{{^isNullable}} || o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}} || o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { @@ -198,7 +198,7 @@ func (o *{{classname}}) Has{{name}}() bool { // Set{{name}} gets a reference to the given {{dataType}} and assigns it to the {{name}} field. {{#deprecated}} -// Deprecated +// Deprecated: Set{{name}} is deprecated. {{/deprecated}} func (o *{{classname}}) Set{{name}}(v {{#isModel}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isModel}}{{vendorExtensions.x-go-base-type}}) *{{classname}} { {{#isNullable}} @@ -216,12 +216,12 @@ func (o *{{classname}}) Set{{name}}(v {{#isModel}}{{^isArray}}{{^isFreeFormObjec } {{#isNullable}} {{^vendorExtensions.x-golang-is-container}} -// Set{{name}}Nil sets the value for {{name}} to be an explicit nil +// Set{{name}}Nil sets the value for {{name}} to be an explicit nil. func (o *{{classname}}) Set{{name}}Nil() { o.{{name}}.Set(nil) } -// Unset{{name}} ensures that no value is present for {{name}}, not even an explicit nil +// Unset{{name}} ensures that no value is present for {{name}}, not even an explicit nil. func (o *{{classname}}) Unset{{name}}() { o.{{name}}.Unset() } @@ -323,7 +323,7 @@ func (o *{{{classname}}}) UnmarshalJSON(bytes []byte) error { // {{{.}}} {{/description}} {{#deprecated}} - // Deprecated + // Deprecated: {{name}} is deprecated. {{/deprecated}} {{name}} {{^required}}{{^isNullable}}{{^isArray}}{{^isFreeFormObject}}*{{/isFreeFormObject}}{{/isArray}}{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"` {{/vars}} diff --git a/templates/go/search_helpers.mustache b/templates/go/search_helpers.mustache index d00624072e6..610b20487c0 100644 --- a/templates/go/search_helpers.mustache +++ b/templates/go/search_helpers.mustache @@ -93,7 +93,7 @@ func (c *APIClient) WaitForTask( return time.Duration(min(200*count, 5000)) * time.Millisecond }), WithMaxRetries(50)}, opts...) - return CreateIterable( //nolint:wrapcheck + return CreateIterable( func(*GetTaskResponse, error) (*GetTaskResponse, error) { return c.GetTask(ctx, indexName, taskID, toRequestOptions(opts)...) }, @@ -121,7 +121,7 @@ func (c *APIClient) WaitForAppTask( return time.Duration(min(200*count, 5000)) * time.Millisecond }), WithMaxRetries(50)}, opts...) - return CreateIterable( //nolint:wrapcheck + return CreateIterable( func(*GetTaskResponse, error) (*GetTaskResponse, error) { return c.GetAppTask(ctx, taskID, toRequestOptions(opts)...) }, @@ -248,7 +248,7 @@ func (c *APIClient) WaitForApiKey( return time.Duration(min(200*count, 5000)) * time.Millisecond }), WithMaxRetries(50)}, opts...) - return CreateIterable( //nolint:wrapcheck + return CreateIterable( func(*GetApiKeyResponse, error) (*GetApiKeyResponse, error) { return c.GetApiKey(ctx, key, toRequestOptions(opts)...) }, @@ -269,7 +269,7 @@ func (c *APIClient) BrowseObjects( browseParams.HitsPerPage = utils.ToPtr(int32(1000)) } - _, err := CreateIterable( //nolint:wrapcheck + _, err := CreateIterable( func(previousResponse *BrowseResponse, previousErr error) (*BrowseResponse, error) { if previousResponse != nil { browseParams.Cursor = previousResponse.Cursor @@ -305,7 +305,7 @@ func (c *APIClient) BrowseRules( hitsPerPage = *optionalParams.HitsPerPage } - _, err := CreateIterable( //nolint:wrapcheck + _, err := CreateIterable( func(previousResponse *SearchRulesResponse, previousErr error) (*SearchRulesResponse, error) { optionalParams.HitsPerPage = &hitsPerPage @@ -348,7 +348,7 @@ func (c *APIClient) BrowseSynonyms( optionalParams.Page = utils.ToPtr(int32(0)) } - _, err := CreateIterable( //nolint:wrapcheck + _, err := CreateIterable( func(previousResponse *SearchSynonymsResponse, previousErr error) (*SearchSynonymsResponse, error) { optionalParams.HitsPerPage = &hitsPerPage @@ -442,7 +442,7 @@ func (c *APIClient) GetSecuredApiKeyRemainingValidity(securedApiKey string) (tim decoded, err := base64.StdEncoding.DecodeString(securedApiKey) if err != nil { - return 0, fmt.Errorf("unable to decode given secured API key: %s", err) + return 0, fmt.Errorf("unable to decode given secured API key: %w", err) } submatch := regexp.MustCompile(`validUntil=(\d{1,10})`).FindSubmatch(decoded) diff --git a/templates/go/snippets/.golangci.mustache b/templates/go/snippets/.golangci.mustache index 326e7421e1f..62870aa2ed9 100644 --- a/templates/go/snippets/.golangci.mustache +++ b/templates/go/snippets/.golangci.mustache @@ -1,12 +1,53 @@ +version: "2" +run: + concurrency: 2 linters: + default: all disable: - - ineffassign - - staticcheck + - cyclop + - depguard + - dupl + - dupword + - exhaustruct + - forbidigo + - forcetypeassert + - funlen + - goconst + - godot + - gomoddirectives + - ireturn + - lll + - maintidx + - mnd + - noctx + - paralleltest + - tagliatelle + - testpackage + - tparallel + - unparam - unused - -issues: - exclude-generated: disable - -run: - concurrency: 2 - timeout: 10m \ No newline at end of file + - varnamelen + - wastedassign + settings: + staticcheck: + checks: ["all", "-SA1019", "-SA4006"] + exclusions: + generated: disable + presets: + - comments + - std-error-handling + rules: + - linters: + - revive + text: "unused-parameter:" +formatters: + enable: + - gofmt + - gofumpt + - goimports + - golines + settings: + golines: + max-len: 150 + exclusions: + generated: disable diff --git a/templates/go/snippets/import.mustache b/templates/go/snippets/import.mustache index b2611f96c8f..4fab4f3172d 100644 --- a/templates/go/snippets/import.mustache +++ b/templates/go/snippets/import.mustache @@ -1 +1,4 @@ -import "github.com/algolia/algoliasearch-client-go/v4/algolia/next/{{clientImport}}" \ No newline at end of file +import ( + "github.com/algolia/algoliasearch-client-go/v4/algolia/next/{{clientImport}}" + "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" +) diff --git a/templates/go/snippets/method.mustache b/templates/go/snippets/method.mustache index d67855fb08e..cc4e4b9dd22 100644 --- a/templates/go/snippets/method.mustache +++ b/templates/go/snippets/method.mustache @@ -6,7 +6,6 @@ package snippets {{> snippets/import}} // IMPORT< - {{#blocksRequests}} {{#snippets}} func SnippetFor{{#lambda.titlecase}}{{method}}{{/lambda.titlecase}}Of{{#lambda.pascalcase}}{{clientPrefix}}{{/lambda.pascalcase}}{{testIndex}}() { diff --git a/templates/go/tests/client/benchmark.mustache b/templates/go/tests/client/benchmark.mustache index 17aac0d64ad..97026140371 100644 --- a/templates/go/tests/client/benchmark.mustache +++ b/templates/go/tests/client/benchmark.mustache @@ -14,6 +14,7 @@ import ( "github.com/algolia/algoliasearch-client-go/v4/algolia/next/{{clientImport}}" "github.com/algolia/algoliasearch-client-go/v4/algolia/transport" "github.com/algolia/algoliasearch-client-go/v4/algolia/call" + "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" ) {{#blocksBenchmark}} diff --git a/templates/go/tests/client/client.mustache b/templates/go/tests/client/client.mustache index 1b4bcd34898..659c99f1186 100644 --- a/templates/go/tests/client/client.mustache +++ b/templates/go/tests/client/client.mustache @@ -6,6 +6,7 @@ import ( "encoding/json" "net/url" "testing" + "time" "regexp" "context" @@ -18,9 +19,12 @@ import ( "github.com/algolia/algoliasearch-client-go/v4/algolia/transport" "github.com/algolia/algoliasearch-client-go/v4/algolia/compression" "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" + "github.com/algolia/algoliasearch-client-go/v4/algolia/call" ) func create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t *testing.T) (*{{clientPrefix}}.APIClient, *tests.EchoRequester) { + t.Helper() + echo := &tests.EchoRequester{} cfg := {{clientPrefix}}.{{clientName}}Configuration{ Configuration: transport.Configuration{ diff --git a/templates/go/tests/client/tests.mustache b/templates/go/tests/client/tests.mustache index f63b9bc8509..f8bbf236d3f 100644 --- a/templates/go/tests/client/tests.mustache +++ b/templates/go/tests/client/tests.mustache @@ -1,6 +1,8 @@ {{#tests}} // {{{testName}}} func Test{{#lambda.titlecase}}{{clientPrefix}}{{testType}}{{/lambda.titlecase}}{{testIndex}}(t *testing.T) { + t.Parallel() + var err error var res any _ = res diff --git a/templates/go/tests/e2e/e2e.mustache b/templates/go/tests/e2e/e2e.mustache index 19d4e31cd8e..df35f4b6f67 100644 --- a/templates/go/tests/e2e/e2e.mustache +++ b/templates/go/tests/e2e/e2e.mustache @@ -3,14 +3,17 @@ package e2e // {{generationBanner}} import ( + "encoding/json" "os" "testing" "context" "github.com/stretchr/testify/require" - + "github.com/kinbiko/jsonassert" "github.com/joho/godotenv" + "gotests/tests" + "github.com/algolia/algoliasearch-client-go/v4/algolia/next/{{clientImport}}" ) @@ -32,8 +35,11 @@ func createE2E{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t {{#blocksE2E}} func Test{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}E2E_{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}(t *testing.T) { + t.Parallel() {{#tests}} t.Run("{{{testName}}}", func(t *testing.T) { + t.Parallel() + client := createE2E{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t) res, err := {{> tests/method}} require.NoError(t, err) diff --git a/templates/go/tests/requests/helpers.mustache b/templates/go/tests/requests/helpers.mustache index e7e957c5179..3383a4794a4 100644 --- a/templates/go/tests/requests/helpers.mustache +++ b/templates/go/tests/requests/helpers.mustache @@ -1,4 +1,6 @@ func TestSearch_GenerateSecuredApiKey(t *testing.T) { + t.Parallel() + client, echo := createSearchClient(t) _ = echo @@ -18,6 +20,8 @@ func TestSearch_GenerateSecuredApiKey(t *testing.T) { } func TestSearch_GetSecuredApiKeyRemainingVaildity(t *testing.T) { + t.Parallel() + client, echo := createSearchClient(t) _ = echo diff --git a/templates/go/tests/requests/requests.mustache b/templates/go/tests/requests/requests.mustache index db85bf50d89..e978db63fd4 100644 --- a/templates/go/tests/requests/requests.mustache +++ b/templates/go/tests/requests/requests.mustache @@ -14,6 +14,7 @@ import ( "github.com/algolia/algoliasearch-client-go/v4/algolia/next/{{clientImport}}" "github.com/algolia/algoliasearch-client-go/v4/algolia/transport" + "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" ) func create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t *testing.T) (*{{clientPrefix}}.APIClient, *tests.EchoRequester) { @@ -36,6 +37,8 @@ func create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t *t {{#blocksRequests}} func Test{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}_{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}(t *testing.T) { + t.Parallel() + client, echo := create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t) _ = echo diff --git a/templates/php/api.mustache b/templates/php/api.mustache index 62417264326..7ccce351f5d 100644 --- a/templates/php/api.mustache +++ b/templates/php/api.mustache @@ -539,7 +539,7 @@ use Algolia\AlgoliaSearch\Exceptions\NotFoundException; * * @param string $indexName The `indexName` to replace `objects` in. * @param array $objects The array of `objects` to store in the given Algolia `indexName`. - * @param bool $createIfNotExists To be provided if non-existing objects are passed, otherwise, the call will fail.. + * @param bool $createIfNotExists To be provided if non-existing objects are passed, otherwise, the call will fail. * @param bool $waitForTasks Whether or not we should wait until every `batch` tasks has been processed, this operation may slow the total execution time of this method but is more reliable * @param array $batchSize The size of the chunk of `objects`. The number of `batch` calls will be equal to `length(objects) / batchSize`. Defaults to 1000. * @param array $requestOptions Request options diff --git a/tests/CTS/requests/common/customGet.json b/tests/CTS/requests/common/customGet.json index 6cb3f59206b..c6730b6cf60 100644 --- a/tests/CTS/requests/common/customGet.json +++ b/tests/CTS/requests/common/customGet.json @@ -30,7 +30,7 @@ "parameters": { "path": "test/all", "parameters": { - "query": "to be overriden" + "query": "to be overridden" } }, "requestOptions": { diff --git a/tests/output/go/.golangci.yml b/tests/output/go/.golangci.yml index b965a94c151..180f2d73427 100644 --- a/tests/output/go/.golangci.yml +++ b/tests/output/go/.golangci.yml @@ -1,14 +1,41 @@ -linters: - disable: - - ineffassign - - staticcheck - -issues: - exclude-generated: disable - - exclude: - - 'printf: non-constant format string in call to' - +version: "2" run: concurrency: 2 - timeout: 10m +linters: + default: all + disable: + - cyclop + - depguard + - dupl + - exhaustruct + - forcetypeassert + - funlen + - goconst + - gomoddirectives + - ireturn + - lll + - maintidx + - mnd + - paralleltest + - testpackage + - tparallel + - wastedassign + settings: + staticcheck: + checks: ["all", "-SA1019", "-SA4006"] + exclusions: + generated: disable + presets: + - comments + - std-error-handling +formatters: + enable: + - gofmt + - gofumpt + - goimports + - golines + settings: + golines: + max-len: 150 + exclusions: + generated: disable diff --git a/tests/output/go/tests/echo.go b/tests/output/go/tests/echo.go index 4f1cde69eb0..5032d2c136f 100644 --- a/tests/output/go/tests/echo.go +++ b/tests/output/go/tests/echo.go @@ -31,6 +31,7 @@ func (e *EchoRequester) Request(req *http.Request, timeout time.Duration, connec e.Header = req.Header e.Timeout = timeout e.ConnectTimeout = connectTimeout + if req.Body != nil { body, _ := io.ReadAll(req.Body) strBody := string(body) @@ -39,8 +40,9 @@ func (e *EchoRequester) Request(req *http.Request, timeout time.Duration, connec e.Body = nil } - var queryValues = strings.Split(req.URL.RawQuery, "&") + queryValues := strings.Split(req.URL.RawQuery, "&") e.Query = url.Values{} + for _, queryValue := range queryValues { split := strings.Split(queryValue, "=") if len(split) == 2 { @@ -49,36 +51,43 @@ func (e *EchoRequester) Request(req *http.Request, timeout time.Duration, connec } return &http.Response{ - StatusCode: 200, + StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString("")), }, nil } func ZeroValue[T any]() T { var v T + return v } func Union(t *testing.T, expected any, received any) any { t.Helper() + if expected != nil { require.NotNil(t, received, expected) } - switch expected.(type) { + switch exp := expected.(type) { case map[string]any: res := map[string]any{} - for key, val := range expected.(map[string]any) { + + for key, val := range exp { require.Contains(t, received.(map[string]any), key) res[key] = Union(t, val, received.(map[string]any)[key]) } + return res case []any: res := []any{} - require.GreaterOrEqual(t, len(received.([]any)), len(expected.([]any))) - for i, val := range expected.([]any) { + + require.GreaterOrEqual(t, len(received.([]any)), len(exp)) + + for i, val := range exp { res = append(res, Union(t, val, received.([]any)[i])) } + return res default: return received